diff --git a/typed_sql/CHANGELOG.md b/typed_sql/CHANGELOG.md index a4e2c875..4b13e242 100644 --- a/typed_sql/CHANGELOG.md +++ b/typed_sql/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.1.14 + * Support `upsertValue` as a shortcut to `insertValue` + `onConflict` + `update`. + ## 0.1.13 * Support `CREATE INDEX` DDLs through `@Index` annotations. diff --git a/typed_sql/example/lib/src/model.g.dart b/typed_sql/example/lib/src/model.g.dart index 87cfdbb3..b6528eaf 100644 --- a/typed_sql/example/lib/src/model.g.dart +++ b/typed_sql/example/lib/src/model.g.dart @@ -138,6 +138,26 @@ extension TableUserExt on Table { values: [userId?.asExpr, name.asExpr, email.asExpr], ); + /// Insert row into the `users` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `email`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? userId, + required String name, + required String email, + }) => insertValue(userId: userId, name: name, email: email) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set(name: excluded.name, email: excluded.email), + ); + /// Bulk insert rows into the `users` table. /// /// This method takes an `Iterable` and requires that you provide @@ -715,6 +735,37 @@ extension TablePackageExt on Table { ], ); + /// Insert row into the `packages` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `likes`, `ownerId`, `publisher`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required String packageName, + int? likes, + required int ownerId, + String? publisher, + }) => + insertValue( + packageName: packageName, + likes: likes, + ownerId: ownerId, + publisher: publisher, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + likes: excluded.likes, + ownerId: excluded.ownerId, + publisher: excluded.publisher, + ), + ); + /// Bulk insert rows into the `packages` table. /// /// This method takes an `Iterable` and requires that you provide @@ -1277,6 +1328,24 @@ extension TableLikeExt on Table { values: [userId.asExpr, packageName.asExpr], ); + /// Insert row into the `likes` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// nothing, as all fields are part of the _primary key_, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required int userId, + required String packageName, + }) => insertValue( + userId: userId, + packageName: packageName, + ).onConflict(.primaryKey).update((_, excluded, set) => set()); + /// Bulk insert rows into the `likes` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/lib/src/codegen/build_code.dart b/typed_sql/lib/src/codegen/build_code.dart index 8abadec2..e7553352 100644 --- a/typed_sql/lib/src/codegen/build_code.dart +++ b/typed_sql/lib/src/codegen/build_code.dart @@ -480,6 +480,62 @@ Iterable buildTable(ParsedTable table, ParsedSchema schema) sync* { ]), ); + /// Parameters for `.insertValue()` and `.upsertValue()`: one named parameter per field. + /// + /// Depending on whether a field has a default value and/or is nullable we + /// have the following cases: + /// + /// 1. `!hasDefault && !isNullable`: + /// The user must give us a value! + /// The parameter is _required_ and non-nullable. + /// + /// 2. `hasDefault && !isNullable`: + /// The user may give us a value, or we can omit the field + /// and the database will insert the _default value_. + /// The parameter is optional and nullable, null means omit + /// the field when inserting the row. + /// + /// 3. `!hasDefault && isNullable`: + /// The user may give us a value, or we can insert `NULL` as + /// the default value -- this also what .insert() does! + /// The parameter is optional and nullable, null means set + /// the field `NULL` when inserting the row. + /// + /// 4. `hasDefault && isNullable`: + /// The user may give us a value, or omit the field to get + /// _default value_, or the user may give `null` meaning + /// `NULL`. We cannot represent all 3 options! + /// We always intepret `null` as `NULL`, thus, the user + /// cannot omit the field and get the _default value_. + /// The user can use `.insert()` instead of `.insertValue()`. + /// This could be surprising which is why we have: + /// * A warning in the documentation, and, + /// * Decided that the parameter is _required_ and nullable. + /// The parameter is _required_ and _nullable_, so that + /// inserting `null` is explicit, not implicit! + /// + /// NOTE: We do not set the default value as _default value_ in + /// dart, because this does not work for auto-increment or + /// for NOW() and similar annotations. + Iterable insertValueParameters() => rowClass.fields.map((field) { + final isOptional = field.hasDefault ^ field.isNullable; + final nullablePostfix = field.hasDefault || field.isNullable ? '?' : ''; + + return Parameter( + (b) => b + ..name = field.name + ..named = true + ..required = !isOptional + ..type = refer('${field.typeName}$nullablePostfix'), + ); + }); + + // Fields that are not part of the _primary key_, these are the fields + // `.upsertValue()` will overwrite when a _primary key_ conflict occurs. + final nonPrimaryKeyFields = rowClass.fields + .where((field) => !rowClass.primaryKey.contains(field)) + .toList(); + // Extension for Table yield Extension( (b) => b @@ -543,57 +599,7 @@ Iterable buildTable(ParsedTable table, ParsedSchema schema) sync* { Returns a [InsertSingle] statement on which `.execute` must be called for the row to be inserted. ''') - ..optionalParameters.addAll( - rowClass.fields.map((field) { - // Depending on whether a field has a default value and/or is - // nullable we have the following cases: - // - // 1. `!hasDefault && !isNullable`: - // The user must give us a value! - // The parameter is _required_ and non-nullable. - // - // 2. `hasDefault && !isNullable`: - // The user may give us a value, or we can omit the field - // and the database will insert the _default value_. - // The parameter is optional and nullable, null means omit - // the field when inserting the row. - // - // 3. `!hasDefault && isNullable`: - // The user may give us a value, or we can insert `NULL` as - // the default value -- this also what .insert() does! - // The parameter is optional and nullable, null means set - // the field `NULL` when inserting the row. - // - // 4. `hasDefault && isNullable`: - // The user may give us a value, or omit the field to get - // _default value_, or the user may give `null` meaning - // `NULL`. We cannot represent all 3 options! - // We always intepret `null` as `NULL`, thus, the user - // cannot omit the field and get the _default value_. - // The user can use `.insert()` instead of `.insertValue()`. - // This could be surprising which is why we have: - // * A warning in the documentation, and, - // * Decided that the parameter is _required_ and nullable. - // The parameter is _required_ and _nullable_, so that - // inserting `null` is explicit, not implicit! - // - // NOTE: We do not set the default value as _default value_ in - // dart, because this does not work for auto-increment or - // for NOW() and similar annotations. - final isOptional = field.hasDefault ^ field.isNullable; - final nullablePostfix = field.hasDefault || field.isNullable - ? '?' - : ''; - - return Parameter( - (b) => b - ..name = field.name - ..named = true - ..required = !isOptional - ..type = refer('${field.typeName}$nullablePostfix'), - ); - }), - ) + ..optionalParameters.addAll(insertValueParameters()) ..returns = refer('InsertSingle<$rowClassName>') ..lambda = true ..body = Code(''' @@ -610,6 +616,41 @@ Iterable buildTable(ParsedTable table, ParsedSchema schema) sync* { '''), ), ) + ..methods.add( + Method( + (b) => b + ..name = 'upsertValue' + ..documentation(''' + Insert row into the `${table.name}` table, or update the + existing row if it conflicts with the _primary key_. + + This is a shorthand for calling `.insertValue(...)` followed by + `.onConflict(.primaryKey)` and `.update(...)` to overwrite + ${nonPrimaryKeyFields.isEmpty ? 'nothing, as all fields are part of the _primary key_,' : 'the fields ${nonPrimaryKeyFields.map((f) => '`${f.name}`').join(', ')},'} + with the values given, leaving the _primary key_ untouched. + + ${rowClass.fields.whereDefaultAndNullable.isEmpty ? '' : '''\n + > [!WARNING] + > It is not possible to insert the _default value_ for fields that + > are nullable. Providing `null` will insert `NULL` for + > ${rowClass.fields.whereDefaultAndNullable.map((f) => '`${f.name}`').join(', ')}. + '''} + + Returns an [UpsertSingle] statement on which `.execute()` must be + called for the row to be inserted or updated. + ''') + ..optionalParameters.addAll(insertValueParameters()) + ..returns = refer('UpsertSingle<$rowClassName>') + ..lambda = true + ..body = Code(''' + insertValue( + ${rowClass.fields.map((field) => '${field.name}: ${field.name}').join(', ')}, + ).onConflict(.primaryKey).update( + (_, excluded, set) => set(${nonPrimaryKeyFields.map((f) => '${f.name}: excluded.${f.name}').join(', ')}), + ) + '''), + ), + ) ..methods.add( Method( (b) => b diff --git a/typed_sql/lib/src/dialect/postgres_dialect.dart b/typed_sql/lib/src/dialect/postgres_dialect.dart index b9fe7b73..0e998360 100644 --- a/typed_sql/lib/src/dialect/postgres_dialect.dart +++ b/typed_sql/lib/src/dialect/postgres_dialect.dart @@ -133,6 +133,13 @@ final class _PostgresDialect extends SqlDialect { '(${c.conflictTarget.map(escape).join(', ')})', 'DO NOTHING', ].join(' '); + case final UpdateOnConflictClause c when c.columns.isEmpty: + // `DO UPDATE SET` requires at least one column, using `DO NOTHING` as no-op. + conflictClause = [ + 'ON CONFLICT', + '(${c.conflictTarget.map(escape).join(', ')})', + 'DO NOTHING', + ].join(' '); case final UpdateOnConflictClause c: final r = resolver .withScope( diff --git a/typed_sql/lib/src/dialect/sqlite_dialect.dart b/typed_sql/lib/src/dialect/sqlite_dialect.dart index 55e43574..b831580f 100644 --- a/typed_sql/lib/src/dialect/sqlite_dialect.dart +++ b/typed_sql/lib/src/dialect/sqlite_dialect.dart @@ -144,6 +144,13 @@ final class _Sqlite extends SqlDialect { '(${c.conflictTarget.map(escape).join(', ')})', 'DO NOTHING', ].join(' '); + case final UpdateOnConflictClause c when c.columns.isEmpty: + // `DO UPDATE SET` requires at least one column, using `DO NOTHING` as no-op. + conflictClause = [ + 'ON CONFLICT', + '(${c.conflictTarget.map(escape).join(', ')})', + 'DO NOTHING', + ].join(' '); case final UpdateOnConflictClause c: final r = resolver .withScope( diff --git a/typed_sql/pubspec.yaml b/typed_sql/pubspec.yaml index 7828795c..8c968449 100644 --- a/typed_sql/pubspec.yaml +++ b/typed_sql/pubspec.yaml @@ -1,5 +1,5 @@ name: typed_sql -version: 0.1.13 +version: 0.1.14 description: Package for doing SQL with some type safety. homepage: https://github.com/google/dart-neats/tree/master/typed_sql repository: https://github.com/google/dart-neats.git diff --git a/typed_sql/test/sqlite/model.g.dart b/typed_sql/test/sqlite/model.g.dart index 09f36696..bff255bc 100644 --- a/typed_sql/test/sqlite/model.g.dart +++ b/typed_sql/test/sqlite/model.g.dart @@ -138,6 +138,26 @@ extension TableUserExt on Table { values: [userId?.asExpr, name.asExpr, email.asExpr], ); + /// Insert row into the `users` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `email`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? userId, + required String name, + required String email, + }) => insertValue(userId: userId, name: name, email: email) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set(name: excluded.name, email: excluded.email), + ); + /// Bulk insert rows into the `users` table. /// /// This method takes an `Iterable` and requires that you provide @@ -734,6 +754,37 @@ extension TablePackageExt on Table { ], ); + /// Insert row into the `packages` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `likes`, `ownerId`, `publisher`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required String packageName, + int? likes, + required int ownerId, + String? publisher, + }) => + insertValue( + packageName: packageName, + likes: likes, + ownerId: ownerId, + publisher: publisher, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + likes: excluded.likes, + ownerId: excluded.ownerId, + publisher: excluded.publisher, + ), + ); + /// Bulk insert rows into the `packages` table. /// /// This method takes an `Iterable` and requires that you provide @@ -1296,6 +1347,24 @@ extension TableLikeExt on Table { values: [userId.asExpr, packageName.asExpr], ); + /// Insert row into the `likes` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// nothing, as all fields are part of the _primary key_, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required int userId, + required String packageName, + }) => insertValue( + userId: userId, + packageName: packageName, + ).onConflict(.primaryKey).update((_, excluded, set) => set()); + /// Bulk insert rows into the `likes` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/aggregates/count_model/count_model_test.g.dart b/typed_sql/test/typed_sql/aggregates/count_model/count_model_test.g.dart index e3ba088d..32d61149 100644 --- a/typed_sql/test/typed_sql/aggregates/count_model/count_model_test.g.dart +++ b/typed_sql/test/typed_sql/aggregates/count_model/count_model_test.g.dart @@ -166,6 +166,40 @@ extension TableItemExt on Table { ], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `text`, `real`, `timestamp`, `integer`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String text, + required double real, + required DateTime timestamp, + int? integer, + }) => + insertValue( + id: id, + text: text, + real: real, + timestamp: timestamp, + integer: integer, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + text: excluded.text, + real: excluded.real, + timestamp: excluded.timestamp, + integer: excluded.integer, + ), + ); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/composite/unionall_null_model/unionall_null_model.g.dart b/typed_sql/test/typed_sql/composite/unionall_null_model/unionall_null_model.g.dart index 2dab1694..da115a1a 100644 --- a/typed_sql/test/typed_sql/composite/unionall_null_model/unionall_null_model.g.dart +++ b/typed_sql/test/typed_sql/composite/unionall_null_model/unionall_null_model.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/crud/blob/blob_test.g.dart b/typed_sql/test/typed_sql/crud/blob/blob_test.g.dart index 7e4f624e..b1521e77 100644 --- a/typed_sql/test/typed_sql/crud/blob/blob_test.g.dart +++ b/typed_sql/test/typed_sql/crud/blob/blob_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required Uint8List value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/crud/boolean/boolean_test.g.dart b/typed_sql/test/typed_sql/crud/boolean/boolean_test.g.dart index 59216019..72397ec7 100644 --- a/typed_sql/test/typed_sql/crud/boolean/boolean_test.g.dart +++ b/typed_sql/test/typed_sql/crud/boolean/boolean_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required bool value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/crud/datetime/datetime_test.g.dart b/typed_sql/test/typed_sql/crud/datetime/datetime_test.g.dart index 82bccdcb..d9c14493 100644 --- a/typed_sql/test/typed_sql/crud/datetime/datetime_test.g.dart +++ b/typed_sql/test/typed_sql/crud/datetime/datetime_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required DateTime value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/crud/integer/integer_test.g.dart b/typed_sql/test/typed_sql/crud/integer/integer_test.g.dart index f6380113..6e6877a9 100644 --- a/typed_sql/test/typed_sql/crud/integer/integer_test.g.dart +++ b/typed_sql/test/typed_sql/crud/integer/integer_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required int value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/crud/json/json_test.g.dart b/typed_sql/test/typed_sql/crud/json/json_test.g.dart index fe962985..0fcd59de 100644 --- a/typed_sql/test/typed_sql/crud/json/json_test.g.dart +++ b/typed_sql/test/typed_sql/crud/json/json_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required JsonValue value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/crud/real/real_test.g.dart b/typed_sql/test/typed_sql/crud/real/real_test.g.dart index 39201dd6..cefd0a32 100644 --- a/typed_sql/test/typed_sql/crud/real/real_test.g.dart +++ b/typed_sql/test/typed_sql/crud/real/real_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required double value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/crud/text/text_test.g.dart b/typed_sql/test/typed_sql/crud/text/text_test.g.dart index b5cece30..7141fa08 100644 --- a/typed_sql/test/typed_sql/crud/text/text_test.g.dart +++ b/typed_sql/test/typed_sql/crud/text/text_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/custom_types/custom_blob/custom_blob_test.g.dart b/typed_sql/test/typed_sql/custom_types/custom_blob/custom_blob_test.g.dart index 751816d4..f130a160 100644 --- a/typed_sql/test/typed_sql/custom_types/custom_blob/custom_blob_test.g.dart +++ b/typed_sql/test/typed_sql/custom_types/custom_blob/custom_blob_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required MyCustomType value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/custom_types/custom_blob_alias/custom_blob_alias_test.g.dart b/typed_sql/test/typed_sql/custom_types/custom_blob_alias/custom_blob_alias_test.g.dart index 42695884..1e437f98 100644 --- a/typed_sql/test/typed_sql/custom_types/custom_blob_alias/custom_blob_alias_test.g.dart +++ b/typed_sql/test/typed_sql/custom_types/custom_blob_alias/custom_blob_alias_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required MyCustomTypeAlias value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/custom_types/custom_boolean/custom_boolean_test.g.dart b/typed_sql/test/typed_sql/custom_types/custom_boolean/custom_boolean_test.g.dart index 5747daab..ad3d4903 100644 --- a/typed_sql/test/typed_sql/custom_types/custom_boolean/custom_boolean_test.g.dart +++ b/typed_sql/test/typed_sql/custom_types/custom_boolean/custom_boolean_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required MyCustomType value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/custom_types/custom_datetime/custom_datetime_test.g.dart b/typed_sql/test/typed_sql/custom_types/custom_datetime/custom_datetime_test.g.dart index 8e65c057..41cad80b 100644 --- a/typed_sql/test/typed_sql/custom_types/custom_datetime/custom_datetime_test.g.dart +++ b/typed_sql/test/typed_sql/custom_types/custom_datetime/custom_datetime_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required MyCustomType value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/custom_types/custom_integer/custom_integer_test.g.dart b/typed_sql/test/typed_sql/custom_types/custom_integer/custom_integer_test.g.dart index d3869c01..91a68b54 100644 --- a/typed_sql/test/typed_sql/custom_types/custom_integer/custom_integer_test.g.dart +++ b/typed_sql/test/typed_sql/custom_types/custom_integer/custom_integer_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required MyCustomType value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/custom_types/custom_json/custom_json_test.g.dart b/typed_sql/test/typed_sql/custom_types/custom_json/custom_json_test.g.dart index f8e751bf..dea022f0 100644 --- a/typed_sql/test/typed_sql/custom_types/custom_json/custom_json_test.g.dart +++ b/typed_sql/test/typed_sql/custom_types/custom_json/custom_json_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required MyCustomType value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/custom_types/custom_json_type/custom_json_type_test.g.dart b/typed_sql/test/typed_sql/custom_types/custom_json_type/custom_json_type_test.g.dart index eae095e6..cc3b3bfa 100644 --- a/typed_sql/test/typed_sql/custom_types/custom_json_type/custom_json_type_test.g.dart +++ b/typed_sql/test/typed_sql/custom_types/custom_json_type/custom_json_type_test.g.dart @@ -112,6 +112,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required JsonValue value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/custom_types/custom_real/custom_real_test.g.dart b/typed_sql/test/typed_sql/custom_types/custom_real/custom_real_test.g.dart index 30856261..84536171 100644 --- a/typed_sql/test/typed_sql/custom_types/custom_real/custom_real_test.g.dart +++ b/typed_sql/test/typed_sql/custom_types/custom_real/custom_real_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required MyCustomType value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/custom_types/custom_text/custom_text_test.g.dart b/typed_sql/test/typed_sql/custom_types/custom_text/custom_text_test.g.dart index f2796227..a070c829 100644 --- a/typed_sql/test/typed_sql/custom_types/custom_text/custom_text_test.g.dart +++ b/typed_sql/test/typed_sql/custom_types/custom_text/custom_text_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required MyCustomType value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/all_default_values/all_default_values_test.g.dart b/typed_sql/test/typed_sql/default/all_default_values/all_default_values_test.g.dart index 2bf4d7c1..430d5478 100644 --- a/typed_sql/test/typed_sql/default/all_default_values/all_default_values_test.g.dart +++ b/typed_sql/test/typed_sql/default/all_default_values/all_default_values_test.g.dart @@ -166,6 +166,40 @@ extension TableItemExt on Table { ], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `birthday`, `createdAt`, `expires`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + String? name, + DateTime? birthday, + DateTime? createdAt, + DateTime? expires, + }) => + insertValue( + id: id, + name: name, + birthday: birthday, + createdAt: createdAt, + expires: expires, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + birthday: excluded.birthday, + createdAt: excluded.createdAt, + expires: excluded.expires, + ), + ); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/default_date_time/default_date_time_test.g.dart b/typed_sql/test/typed_sql/default/default_date_time/default_date_time_test.g.dart index bc9fcd09..76a12f39 100644 --- a/typed_sql/test/typed_sql/default/default_date_time/default_date_time_test.g.dart +++ b/typed_sql/test/typed_sql/default/default_date_time/default_date_time_test.g.dart @@ -166,6 +166,40 @@ extension TableItemExt on Table { ], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `birthday`, `createdAt`, `expires`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String name, + DateTime? birthday, + DateTime? createdAt, + DateTime? expires, + }) => + insertValue( + id: id, + name: name, + birthday: birthday, + createdAt: createdAt, + expires: expires, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + birthday: excluded.birthday, + createdAt: excluded.createdAt, + expires: excluded.expires, + ), + ); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/default_int_for_double/default_int_for_double_test.g.dart b/typed_sql/test/typed_sql/default/default_int_for_double/default_int_for_double_test.g.dart index 3f5e00d5..0504ab10 100644 --- a/typed_sql/test/typed_sql/default/default_int_for_double/default_int_for_double_test.g.dart +++ b/typed_sql/test/typed_sql/default/default_int_for_double/default_int_for_double_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, double? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value?.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, double? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/default_nullable_int/default_nullable_int_test.g.dart b/typed_sql/test/typed_sql/default/default_nullable_int/default_nullable_int_test.g.dart index 07225c65..22a84b0e 100644 --- a/typed_sql/test/typed_sql/default/default_nullable_int/default_nullable_int_test.g.dart +++ b/typed_sql/test/typed_sql/default/default_nullable_int/default_nullable_int_test.g.dart @@ -114,6 +114,26 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// > [!WARNING] + /// > It is not possible to insert the _default value_ for fields that + /// > are nullable. Providing `null` will insert `NULL` for + /// > `value`. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required int? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/int_cast_test/int_cast_test.g.dart b/typed_sql/test/typed_sql/default/int_cast_test/int_cast_test.g.dart index ad57505f..86f40326 100644 --- a/typed_sql/test/typed_sql/default/int_cast_test/int_cast_test.g.dart +++ b/typed_sql/test/typed_sql/default/int_cast_test/int_cast_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, double? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value?.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, double? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/types/default_boolean/default_boolean_test.g.dart b/typed_sql/test/typed_sql/default/types/default_boolean/default_boolean_test.g.dart index 1a8d7153..855db544 100644 --- a/typed_sql/test/typed_sql/default/types/default_boolean/default_boolean_test.g.dart +++ b/typed_sql/test/typed_sql/default/types/default_boolean/default_boolean_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, bool? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value?.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, bool? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/types/default_integer/default_integer_test.g.dart b/typed_sql/test/typed_sql/default/types/default_integer/default_integer_test.g.dart index 09a3f6d8..66319285 100644 --- a/typed_sql/test/typed_sql/default/types/default_integer/default_integer_test.g.dart +++ b/typed_sql/test/typed_sql/default/types/default_integer/default_integer_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, int? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value?.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, int? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/types/default_json/default_json_test.g.dart b/typed_sql/test/typed_sql/default/types/default_json/default_json_test.g.dart index 8a9933c7..b3e296c0 100644 --- a/typed_sql/test/typed_sql/default/types/default_json/default_json_test.g.dart +++ b/typed_sql/test/typed_sql/default/types/default_json/default_json_test.g.dart @@ -112,6 +112,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value?.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, JsonValue? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/types/default_json_nested_structures/default_json_nested_structures_test.g.dart b/typed_sql/test/typed_sql/default/types/default_json_nested_structures/default_json_nested_structures_test.g.dart index 116e02a7..01bb8a50 100644 --- a/typed_sql/test/typed_sql/default/types/default_json_nested_structures/default_json_nested_structures_test.g.dart +++ b/typed_sql/test/typed_sql/default/types/default_json_nested_structures/default_json_nested_structures_test.g.dart @@ -128,6 +128,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value?.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, JsonValue? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/types/default_json_single_quote/default_json_single_quote_test.g.dart b/typed_sql/test/typed_sql/default/types/default_json_single_quote/default_json_single_quote_test.g.dart index 8827e59f..a8b98207 100644 --- a/typed_sql/test/typed_sql/default/types/default_json_single_quote/default_json_single_quote_test.g.dart +++ b/typed_sql/test/typed_sql/default/types/default_json_single_quote/default_json_single_quote_test.g.dart @@ -112,6 +112,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value?.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, JsonValue? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/types/default_nullable_text/default_nullable_text_test.g.dart b/typed_sql/test/typed_sql/default/types/default_nullable_text/default_nullable_text_test.g.dart index 333de886..e3b88a85 100644 --- a/typed_sql/test/typed_sql/default/types/default_nullable_text/default_nullable_text_test.g.dart +++ b/typed_sql/test/typed_sql/default/types/default_nullable_text/default_nullable_text_test.g.dart @@ -114,6 +114,26 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// > [!WARNING] + /// > It is not possible to insert the _default value_ for fields that + /// > are nullable. Providing `null` will insert `NULL` for + /// > `value`. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/types/default_real/default_real_test.g.dart b/typed_sql/test/typed_sql/default/types/default_real/default_real_test.g.dart index 39eff4c0..fa028334 100644 --- a/typed_sql/test/typed_sql/default/types/default_real/default_real_test.g.dart +++ b/typed_sql/test/typed_sql/default/types/default_real/default_real_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, double? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value?.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, double? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/types/default_text/default_text_test.g.dart b/typed_sql/test/typed_sql/default/types/default_text/default_text_test.g.dart index 90d68341..5f114608 100644 --- a/typed_sql/test/typed_sql/default/types/default_text/default_text_test.g.dart +++ b/typed_sql/test/typed_sql/default/types/default_text/default_text_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, String? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value?.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, String? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/default/types/default_zero_real/default_zero_real_test.g.dart b/typed_sql/test/typed_sql/default/types/default_zero_real/default_zero_real_test.g.dart index f6a74526..0cd08382 100644 --- a/typed_sql/test/typed_sql/default/types/default_zero_real/default_zero_real_test.g.dart +++ b/typed_sql/test/typed_sql/default/types/default_zero_real/default_zero_real_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, double? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value?.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, double? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/distinct/distinct_model/distinct_model_test.g.dart b/typed_sql/test/typed_sql/distinct/distinct_model/distinct_model_test.g.dart index f6673f7f..de6f8b7f 100644 --- a/typed_sql/test/typed_sql/distinct/distinct_model/distinct_model_test.g.dart +++ b/typed_sql/test/typed_sql/distinct/distinct_model/distinct_model_test.g.dart @@ -160,6 +160,34 @@ extension TableItemExt on Table { values: [id?.asExpr, text.asExpr, integer.asExpr, real.asExpr, json.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `text`, `integer`, `real`, `json`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String text, + required int integer, + required double real, + required JsonValue json, + }) => + insertValue(id: id, text: text, integer: integer, real: real, json: json) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + text: excluded.text, + integer: excluded.integer, + real: excluded.real, + json: excluded.json, + ), + ); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/distinct/distinct_model_null/distinct_model_null_test.g.dart b/typed_sql/test/typed_sql/distinct/distinct_model_null/distinct_model_null_test.g.dart index a3647382..2e325c4d 100644 --- a/typed_sql/test/typed_sql/distinct/distinct_model_null/distinct_model_null_test.g.dart +++ b/typed_sql/test/typed_sql/distinct/distinct_model_null/distinct_model_null_test.g.dart @@ -160,6 +160,34 @@ extension TableItemExt on Table { values: [id?.asExpr, text.asExpr, integer.asExpr, real.asExpr, json.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `text`, `integer`, `real`, `json`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + String? text, + int? integer, + double? real, + JsonValue? json, + }) => + insertValue(id: id, text: text, integer: integer, real: real, json: json) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + text: excluded.text, + integer: excluded.integer, + real: excluded.real, + json: excluded.json, + ), + ); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/documentation/model_documentation_test.g.dart b/typed_sql/test/typed_sql/documentation/model_documentation_test.g.dart index 60507309..35915414 100644 --- a/typed_sql/test/typed_sql/documentation/model_documentation_test.g.dart +++ b/typed_sql/test/typed_sql/documentation/model_documentation_test.g.dart @@ -145,6 +145,34 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, name.asExpr, favoriteBookId.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `favoriteBookId`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? authorId, + required String name, + int? favoriteBookId, + }) => + insertValue( + authorId: authorId, + name: name, + favoriteBookId: favoriteBookId, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + favoriteBookId: excluded.favoriteBookId, + ), + ); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -838,6 +866,40 @@ extension TableBookExt on Table { ], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `editorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + required int authorId, + int? editorId, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + editorId: editorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + editorId: excluded.editorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/bank/bank_test.g.dart b/typed_sql/test/typed_sql/example/bank/bank_test.g.dart index bff2bdc3..c1670c90 100644 --- a/typed_sql/test/typed_sql/example/bank/bank_test.g.dart +++ b/typed_sql/test/typed_sql/example/bank/bank_test.g.dart @@ -140,6 +140,34 @@ extension TableAccountExt on Table { values: [accountId?.asExpr, accountNumber.asExpr, balance?.asExpr], ); + /// Insert row into the `accounts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `accountNumber`, `balance`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? accountId, + required String accountNumber, + double? balance, + }) => + insertValue( + accountId: accountId, + accountNumber: accountNumber, + balance: balance, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + accountNumber: excluded.accountNumber, + balance: excluded.balance, + ), + ); + /// Bulk insert rows into the `accounts` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/blog/blog_test.g.dart b/typed_sql/test/typed_sql/example/blog/blog_test.g.dart index 6d9df1da..8ffaea7a 100644 --- a/typed_sql/test/typed_sql/example/blog/blog_test.g.dart +++ b/typed_sql/test/typed_sql/example/blog/blog_test.g.dart @@ -147,6 +147,24 @@ extension TablePostExt on Table { values: [author.asExpr, slug.asExpr, content.asExpr], ); + /// Insert row into the `posts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `content`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required String author, + required String slug, + required String content, + }) => insertValue(author: author, slug: slug, content: content) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(content: excluded.content)); + /// Bulk insert rows into the `posts` table. /// /// This method takes an `Iterable` and requires that you provide @@ -732,6 +750,37 @@ extension TableCommentExt on Table { values: [commentId.asExpr, author.asExpr, postSlug.asExpr, comment.asExpr], ); + /// Insert row into the `comments` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `author`, `postSlug`, `comment`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required int commentId, + required String author, + required String postSlug, + required String comment, + }) => + insertValue( + commentId: commentId, + author: author, + postSlug: postSlug, + comment: comment, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + author: excluded.author, + postSlug: excluded.postSlug, + comment: excluded.comment, + ), + ); + /// Bulk insert rows into the `comments` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/bookstore/bookstore_test.g.dart b/typed_sql/test/typed_sql/example/bookstore/bookstore_test.g.dart index 28f768ba..56f472bc 100644 --- a/typed_sql/test/typed_sql/example/bookstore/bookstore_test.g.dart +++ b/typed_sql/test/typed_sql/example/bookstore/bookstore_test.g.dart @@ -123,6 +123,21 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, name.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? authorId, required String name}) => + insertValue(authorId: authorId, name: name) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(name: excluded.name)); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -672,6 +687,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock?.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + String? title, + required int authorId, + int? stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/company/company_test.g.dart b/typed_sql/test/typed_sql/example/company/company_test.g.dart index 4231fffd..e9165632 100644 --- a/typed_sql/test/typed_sql/example/company/company_test.g.dart +++ b/typed_sql/test/typed_sql/example/company/company_test.g.dart @@ -137,6 +137,27 @@ extension TableDepartmentExt on Table { values: [departmentId?.asExpr, name.asExpr, location.asExpr], ); + /// Insert row into the `departments` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `location`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? departmentId, + required String name, + required String location, + }) => insertValue(departmentId: departmentId, name: name, location: location) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, location: excluded.location), + ); + /// Bulk insert rows into the `departments` table. /// /// This method takes an `Iterable` and requires that you provide @@ -694,6 +715,32 @@ extension TableEmployeeExt on Table { values: [employeeId?.asExpr, name.asExpr, departmentId.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `departmentId`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? employeeId, + required String name, + int? departmentId, + }) => + insertValue( + employeeId: employeeId, + name: name, + departmentId: departmentId, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, departmentId: excluded.departmentId), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/dealership/dealership_test.g.dart b/typed_sql/test/typed_sql/example/dealership/dealership_test.g.dart index 75ce5448..7b846e1d 100644 --- a/typed_sql/test/typed_sql/example/dealership/dealership_test.g.dart +++ b/typed_sql/test/typed_sql/example/dealership/dealership_test.g.dart @@ -155,6 +155,37 @@ extension TableCarExt on Table { values: [id?.asExpr, model.asExpr, licensePlate.asExpr, color.asExpr], ); + /// Insert row into the `cars` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `model`, `licensePlate`, `color`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String model, + required String licensePlate, + required Color color, + }) => + insertValue( + id: id, + model: model, + licensePlate: licensePlate, + color: color, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + model: excluded.model, + licensePlate: excluded.licensePlate, + color: excluded.color, + ), + ); + /// Bulk insert rows into the `cars` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/migration/lib/model.g.dart b/typed_sql/test/typed_sql/example/migration/lib/model.g.dart index dfdf6e8e..cca1e7be 100644 --- a/typed_sql/test/typed_sql/example/migration/lib/model.g.dart +++ b/typed_sql/test/typed_sql/example/migration/lib/model.g.dart @@ -127,6 +127,23 @@ extension TableAccountExt on Table { values: [accountId?.asExpr, accountNumber.asExpr], ); + /// Insert row into the `accounts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `accountNumber`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? accountId, + required String accountNumber, + }) => insertValue(accountId: accountId, accountNumber: accountNumber) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(accountNumber: excluded.accountNumber)); + /// Bulk insert rows into the `accounts` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/migration/lib/patched_model.g.dart b/typed_sql/test/typed_sql/example/migration/lib/patched_model.g.dart index ad7b179e..5e83561d 100644 --- a/typed_sql/test/typed_sql/example/migration/lib/patched_model.g.dart +++ b/typed_sql/test/typed_sql/example/migration/lib/patched_model.g.dart @@ -140,6 +140,34 @@ extension TableAccountExt on Table { values: [accountId?.asExpr, accountNumber.asExpr, balance?.asExpr], ); + /// Insert row into the `accounts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `accountNumber`, `balance`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? accountId, + required String accountNumber, + double? balance, + }) => + insertValue( + accountId: accountId, + accountNumber: accountNumber, + balance: balance, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + accountNumber: excluded.accountNumber, + balance: excluded.balance, + ), + ); + /// Bulk insert rows into the `accounts` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/schema/schema_default_value/schema_default_value_test.g.dart b/typed_sql/test/typed_sql/example/schema/schema_default_value/schema_default_value_test.g.dart index f0266968..0e68ff45 100644 --- a/typed_sql/test/typed_sql/example/schema/schema_default_value/schema_default_value_test.g.dart +++ b/typed_sql/test/typed_sql/example/schema/schema_default_value/schema_default_value_test.g.dart @@ -123,6 +123,21 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, name.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? authorId, required String name}) => + insertValue(authorId: authorId, name: name) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(name: excluded.name)); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -672,6 +687,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock?.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + String? title, + required int authorId, + int? stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/schema/schema_overrides/schema_overrides_test.g.dart b/typed_sql/test/typed_sql/example/schema/schema_overrides/schema_overrides_test.g.dart index 68dd4d87..8a3d37f2 100644 --- a/typed_sql/test/typed_sql/example/schema/schema_overrides/schema_overrides_test.g.dart +++ b/typed_sql/test/typed_sql/example/schema/schema_overrides/schema_overrides_test.g.dart @@ -130,6 +130,21 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, name.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? authorId, required String name}) => + insertValue(authorId: authorId, name: name) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(name: excluded.name)); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -679,6 +694,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock?.asExpr], ); + /// Insert row into the `booksInStock` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + String? title, + required int authorId, + int? stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `booksInStock` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/schema/schema_references/schema_references_test.g.dart b/typed_sql/test/typed_sql/example/schema/schema_references/schema_references_test.g.dart index 59b81f8f..a0dd93d2 100644 --- a/typed_sql/test/typed_sql/example/schema/schema_references/schema_references_test.g.dart +++ b/typed_sql/test/typed_sql/example/schema/schema_references/schema_references_test.g.dart @@ -123,6 +123,21 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, name.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? authorId, required String name}) => + insertValue(authorId: authorId, name: name) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(name: excluded.name)); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -672,6 +687,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock?.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + String? title, + required int authorId, + int? stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/example/testing/model.g.dart b/typed_sql/test/typed_sql/example/testing/model.g.dart index 70b9b92e..107085d4 100644 --- a/typed_sql/test/typed_sql/example/testing/model.g.dart +++ b/typed_sql/test/typed_sql/example/testing/model.g.dart @@ -140,6 +140,34 @@ extension TableAccountExt on Table { values: [accountId?.asExpr, accountNumber.asExpr, balance?.asExpr], ); + /// Insert row into the `accounts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `accountNumber`, `balance`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? accountId, + required String accountNumber, + double? balance, + }) => + insertValue( + accountId: accountId, + accountNumber: accountNumber, + balance: balance, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + accountNumber: excluded.accountNumber, + balance: excluded.balance, + ), + ); + /// Bulk insert rows into the `accounts` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/foreign_key/advanced_composite_fk/advanced_composite_fk_test.g.dart b/typed_sql/test/typed_sql/foreign_key/advanced_composite_fk/advanced_composite_fk_test.g.dart index b327526e..de62080a 100644 --- a/typed_sql/test/typed_sql/foreign_key/advanced_composite_fk/advanced_composite_fk_test.g.dart +++ b/typed_sql/test/typed_sql/foreign_key/advanced_composite_fk/advanced_composite_fk_test.g.dart @@ -147,6 +147,24 @@ extension TablePostExt on Table { values: [author.asExpr, slug.asExpr, content.asExpr], ); + /// Insert row into the `posts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `content`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required String author, + required String slug, + required String content, + }) => insertValue(author: author, slug: slug, content: content) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(content: excluded.content)); + /// Bulk insert rows into the `posts` table. /// /// This method takes an `Iterable` and requires that you provide @@ -732,6 +750,37 @@ extension TableCommentExt on Table { values: [commentId?.asExpr, author.asExpr, postSlug.asExpr, comment.asExpr], ); + /// Insert row into the `comments` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `author`, `postSlug`, `comment`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? commentId, + required String author, + required String postSlug, + required String comment, + }) => + insertValue( + commentId: commentId, + author: author, + postSlug: postSlug, + comment: comment, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + author: excluded.author, + postSlug: excluded.postSlug, + comment: excluded.comment, + ), + ); + /// Bulk insert rows into the `comments` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/foreign_key/composite_foreign_key/composite_foreign_key_test.g.dart b/typed_sql/test/typed_sql/foreign_key/composite_foreign_key/composite_foreign_key_test.g.dart index 20c9f5f8..04a2e426 100644 --- a/typed_sql/test/typed_sql/foreign_key/composite_foreign_key/composite_foreign_key_test.g.dart +++ b/typed_sql/test/typed_sql/foreign_key/composite_foreign_key/composite_foreign_key_test.g.dart @@ -131,6 +131,24 @@ extension TableAuthorExt on Table { values: [firstName.asExpr, lastName.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// nothing, as all fields are part of the _primary key_, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required String firstName, + required String lastName, + }) => insertValue( + firstName: firstName, + lastName: lastName, + ).onConflict(.primaryKey).update((_, excluded, set) => set()); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -741,6 +759,40 @@ extension TableBookExt on Table { ], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorFirstName`, `authorLastName`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + required String authorFirstName, + required String authorLastName, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorFirstName: authorFirstName, + authorLastName: authorLastName, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorFirstName: excluded.authorFirstName, + authorLastName: excluded.authorLastName, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/foreign_key/nullable_composite_foreign_key/nullable_composite_foreign_key_test.g.dart b/typed_sql/test/typed_sql/foreign_key/nullable_composite_foreign_key/nullable_composite_foreign_key_test.g.dart index a08b6908..4283e0a7 100644 --- a/typed_sql/test/typed_sql/foreign_key/nullable_composite_foreign_key/nullable_composite_foreign_key_test.g.dart +++ b/typed_sql/test/typed_sql/foreign_key/nullable_composite_foreign_key/nullable_composite_foreign_key_test.g.dart @@ -131,6 +131,24 @@ extension TableAuthorExt on Table { values: [firstName.asExpr, lastName.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// nothing, as all fields are part of the _primary key_, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required String firstName, + required String lastName, + }) => insertValue( + firstName: firstName, + lastName: lastName, + ).onConflict(.primaryKey).update((_, excluded, set) => set()); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -741,6 +759,40 @@ extension TableBookExt on Table { ], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorFirstName`, `authorLastName`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + String? authorFirstName, + String? authorLastName, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorFirstName: authorFirstName, + authorLastName: authorLastName, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorFirstName: excluded.authorFirstName, + authorLastName: excluded.authorLastName, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_cascade_foreign_key_test.g.dart b/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_cascade_foreign_key_test.g.dart index 5c970f88..09fe734f 100644 --- a/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_cascade_foreign_key_test.g.dart +++ b/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_cascade_foreign_key_test.g.dart @@ -133,6 +133,28 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, firstname.asExpr, lastname.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstname`, `lastname`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? authorId, + required String firstname, + required String lastname, + }) => + insertValue(authorId: authorId, firstname: firstname, lastname: lastname) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(firstname: excluded.firstname, lastname: excluded.lastname), + ); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -709,6 +731,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + int? authorId, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_no_action_foreign_key_test.g.dart b/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_no_action_foreign_key_test.g.dart index 62e2d16d..67ad5789 100644 --- a/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_no_action_foreign_key_test.g.dart +++ b/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_no_action_foreign_key_test.g.dart @@ -133,6 +133,28 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, firstname.asExpr, lastname.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstname`, `lastname`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? authorId, + required String firstname, + required String lastname, + }) => + insertValue(authorId: authorId, firstname: firstname, lastname: lastname) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(firstname: excluded.firstname, lastname: excluded.lastname), + ); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -709,6 +731,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + int? authorId, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_restrict_foreign_key_test.g.dart b/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_restrict_foreign_key_test.g.dart index 28c8da46..b44c948c 100644 --- a/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_restrict_foreign_key_test.g.dart +++ b/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_restrict_foreign_key_test.g.dart @@ -133,6 +133,28 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, firstname.asExpr, lastname.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstname`, `lastname`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? authorId, + required String firstname, + required String lastname, + }) => + insertValue(authorId: authorId, firstname: firstname, lastname: lastname) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(firstname: excluded.firstname, lastname: excluded.lastname), + ); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -709,6 +731,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + int? authorId, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_set_nulls_foreign_key_test.g.dart b/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_set_nulls_foreign_key_test.g.dart index 3f35eddd..eed50cd6 100644 --- a/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_set_nulls_foreign_key_test.g.dart +++ b/typed_sql/test/typed_sql/foreign_key/on_referential_event_foreign_key/on_referential_event_set_nulls_foreign_key_test.g.dart @@ -133,6 +133,28 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, firstname.asExpr, lastname.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstname`, `lastname`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? authorId, + required String firstname, + required String lastname, + }) => + insertValue(authorId: authorId, firstname: firstname, lastname: lastname) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(firstname: excluded.firstname, lastname: excluded.lastname), + ); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -709,6 +731,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + int? authorId, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/foreign_key/simple_foreign_key/simple_foreign_key_test.g.dart b/typed_sql/test/typed_sql/foreign_key/simple_foreign_key/simple_foreign_key_test.g.dart index c2b80b58..c7be4188 100644 --- a/typed_sql/test/typed_sql/foreign_key/simple_foreign_key/simple_foreign_key_test.g.dart +++ b/typed_sql/test/typed_sql/foreign_key/simple_foreign_key/simple_foreign_key_test.g.dart @@ -133,6 +133,28 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, firstname.asExpr, lastname.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstname`, `lastname`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? authorId, + required String firstname, + required String lastname, + }) => + insertValue(authorId: authorId, firstname: firstname, lastname: lastname) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(firstname: excluded.firstname, lastname: excluded.lastname), + ); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -709,6 +731,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + required int authorId, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_bugs/group_by_bugs_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_bugs/group_by_bugs_test.g.dart index ef9e8510..1fc29235 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_bugs/group_by_bugs_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_bugs/group_by_bugs_test.g.dart @@ -143,6 +143,31 @@ extension TableItemExt on Table { values: [id?.asExpr, category.asExpr, data.asExpr, score.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `category`, `data`, `score`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String category, + required JsonValue data, + required int score, + }) => insertValue(id: id, category: category, data: data, score: score) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + category: excluded.category, + data: excluded.data, + score: excluded.score, + ), + ); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_composite/group_by_composite_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_composite/group_by_composite_test.g.dart index 2c62c9c3..49b8ae38 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_composite/group_by_composite_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_composite/group_by_composite_test.g.dart @@ -304,6 +304,58 @@ extension TableItemExt on Table { ], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `text`, `real`, `integer`, `timestamp`, `json`, `optText`, `optReal`, `optInteger`, `optTimestamp`, `optJson`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String text, + required double real, + required int integer, + required DateTime timestamp, + required JsonValue json, + String? optText, + double? optReal, + int? optInteger, + DateTime? optTimestamp, + JsonValue? optJson, + }) => + insertValue( + id: id, + text: text, + real: real, + integer: integer, + timestamp: timestamp, + json: json, + optText: optText, + optReal: optReal, + optInteger: optInteger, + optTimestamp: optTimestamp, + optJson: optJson, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + text: excluded.text, + real: excluded.real, + integer: excluded.integer, + timestamp: excluded.timestamp, + json: excluded.json, + optText: excluded.optText, + optReal: excluded.optReal, + optInteger: excluded.optInteger, + optTimestamp: excluded.optTimestamp, + optJson: excluded.optJson, + ), + ); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_expression/group_by_expression_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_expression/group_by_expression_test.g.dart index 60b3b5fe..ea98d0c3 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_expression/group_by_expression_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_expression/group_by_expression_test.g.dart @@ -129,6 +129,27 @@ extension TableEmployeeExt on Table { values: [id?.asExpr, surname.asExpr, salary.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `surname`, `salary`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String surname, + required int salary, + }) => insertValue(id: id, surname: surname, salary: salary) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(surname: excluded.surname, salary: excluded.salary), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_having/group_by_having_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_having/group_by_having_test.g.dart index a41df596..71a5288c 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_having/group_by_having_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_having/group_by_having_test.g.dart @@ -129,6 +129,27 @@ extension TableEmployeeExt on Table { values: [id?.asExpr, surname.asExpr, salary.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `surname`, `salary`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String surname, + required int salary, + }) => insertValue(id: id, surname: surname, salary: salary) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(surname: excluded.surname, salary: excluded.salary), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_join_complex/complex_aggregations_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_join_complex/complex_aggregations_test.g.dart index 931c04d2..9616d43d 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_join_complex/complex_aggregations_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_join_complex/complex_aggregations_test.g.dart @@ -135,6 +135,23 @@ extension TableDepartmentExt on Table { values: [departmentId?.asExpr, name.asExpr], ); + /// Insert row into the `departments` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? departmentId, + required String name, + }) => insertValue(departmentId: departmentId, name: name) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(name: excluded.name)); + /// Bulk insert rows into the `departments` table. /// /// This method takes an `Iterable` and requires that you provide @@ -614,6 +631,32 @@ extension TableEmployeeExt on Table { values: [employeeId?.asExpr, name.asExpr, departmentId.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `departmentId`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? employeeId, + required String name, + required int departmentId, + }) => + insertValue( + employeeId: employeeId, + name: name, + departmentId: departmentId, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, departmentId: excluded.departmentId), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide @@ -1140,6 +1183,37 @@ extension TableProjectExt on Table { ], ); + /// Insert row into the `projects` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `departmentId`, `budget`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? projectId, + required String name, + required int departmentId, + required int budget, + }) => + insertValue( + projectId: projectId, + name: name, + departmentId: departmentId, + budget: budget, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + departmentId: excluded.departmentId, + budget: excluded.budget, + ), + ); + /// Bulk insert rows into the `projects` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_join_expression/group_by_join_expression_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_join_expression/group_by_join_expression_test.g.dart index add954f0..a95a0e44 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_join_expression/group_by_join_expression_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_join_expression/group_by_join_expression_test.g.dart @@ -115,6 +115,21 @@ extension TableDepartmentExt on Table { values: [id?.asExpr, name.asExpr], ); + /// Insert row into the `departments` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String name}) => + insertValue(id: id, name: name) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(name: excluded.name)); + /// Bulk insert rows into the `departments` table. /// /// This method takes an `Iterable` and requires that you provide @@ -590,6 +605,31 @@ extension TableEmployeeExt on Table { values: [id?.asExpr, name.asExpr, deptId.asExpr, salary.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `deptId`, `salary`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String name, + required int deptId, + required int salary, + }) => insertValue(id: id, name: name, deptId: deptId, salary: salary) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + deptId: excluded.deptId, + salary: excluded.salary, + ), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_json/json_groupby_caveat_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_json/json_groupby_caveat_test.g.dart index 5d72696f..7a1b7afd 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_json/json_groupby_caveat_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_json/json_groupby_caveat_test.g.dart @@ -128,6 +128,27 @@ extension TableProductExt on Table { values: [id?.asExpr, name.asExpr, metadata.asExpr], ); + /// Insert row into the `products` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `metadata`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String name, + required JsonValue metadata, + }) => insertValue(id: id, name: name, metadata: metadata) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, metadata: excluded.metadata), + ); + /// Bulk insert rows into the `products` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_null/group_by_null_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_null/group_by_null_test.g.dart index 4226c94c..bc1c732e 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_null/group_by_null_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_null/group_by_null_test.g.dart @@ -144,6 +144,37 @@ extension TableEmployeeExt on Table { values: [id?.asExpr, surname.asExpr, seniority.asExpr, salary.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `surname`, `seniority`, `salary`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String surname, + required String seniority, + int? salary, + }) => + insertValue( + id: id, + surname: surname, + seniority: seniority, + salary: salary, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + surname: excluded.surname, + seniority: excluded.seniority, + salary: excluded.salary, + ), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_reference/group_by_reference_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_reference/group_by_reference_test.g.dart index f44f076c..f44d736c 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_reference/group_by_reference_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_reference/group_by_reference_test.g.dart @@ -114,6 +114,21 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, name.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? authorId, required String name}) => + insertValue(authorId: authorId, name: name) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(name: excluded.name)); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -635,6 +650,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + required int authorId, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/group_by/group_by_string/group_by_string_test.g.dart b/typed_sql/test/typed_sql/group_by/group_by_string/group_by_string_test.g.dart index 03abf733..522eca36 100644 --- a/typed_sql/test/typed_sql/group_by/group_by_string/group_by_string_test.g.dart +++ b/typed_sql/test/typed_sql/group_by/group_by_string/group_by_string_test.g.dart @@ -144,6 +144,37 @@ extension TableEmployeeExt on Table { values: [id?.asExpr, surname.asExpr, seniority.asExpr, salary.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `surname`, `seniority`, `salary`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String surname, + required String seniority, + int? salary, + }) => + insertValue( + id: id, + surname: surname, + seniority: seniority, + salary: salary, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + surname: excluded.surname, + seniority: excluded.seniority, + salary: excluded.salary, + ), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/all_types/all_types_test.g.dart b/typed_sql/test/typed_sql/insert/all_types/all_types_test.g.dart index 6dec10c2..fbcbc1e1 100644 --- a/typed_sql/test/typed_sql/insert/all_types/all_types_test.g.dart +++ b/typed_sql/test/typed_sql/insert/all_types/all_types_test.g.dart @@ -542,6 +542,94 @@ extension TableAllTypesItemExt on Table { ], ); + /// Insert row into the `allTypesItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `b`, `i`, `d`, `s`, `dt`, `blob`, `json`, `custom`, `nb`, `ni`, `nd`, `ns`, `ndt`, `nblob`, `njson`, `ncustom`, `db`, `di`, `dd`, `ds`, `ddt`, `djson`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required bool b, + required int i, + required double d, + required String s, + required DateTime dt, + required Uint8List blob, + required JsonValue json, + required MyCustomType custom, + bool? nb, + int? ni, + double? nd, + String? ns, + DateTime? ndt, + Uint8List? nblob, + JsonValue? njson, + MyCustomType? ncustom, + bool? db, + int? di, + double? dd, + String? ds, + DateTime? ddt, + JsonValue? djson, + }) => + insertValue( + id: id, + b: b, + i: i, + d: d, + s: s, + dt: dt, + blob: blob, + json: json, + custom: custom, + nb: nb, + ni: ni, + nd: nd, + ns: ns, + ndt: ndt, + nblob: nblob, + njson: njson, + ncustom: ncustom, + db: db, + di: di, + dd: dd, + ds: ds, + ddt: ddt, + djson: djson, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + b: excluded.b, + i: excluded.i, + d: excluded.d, + s: excluded.s, + dt: excluded.dt, + blob: excluded.blob, + json: excluded.json, + custom: excluded.custom, + nb: excluded.nb, + ni: excluded.ni, + nd: excluded.nd, + ns: excluded.ns, + ndt: excluded.ndt, + nblob: excluded.nblob, + njson: excluded.njson, + ncustom: excluded.ncustom, + db: excluded.db, + di: excluded.di, + dd: excluded.dd, + ds: excluded.ds, + ddt: excluded.ddt, + djson: excluded.djson, + ), + ); + /// Bulk insert rows into the `allTypesItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/complex_constraints/complex_constraints_test.g.dart b/typed_sql/test/typed_sql/insert/complex_constraints/complex_constraints_test.g.dart index b07c8dbe..8321f26d 100644 --- a/typed_sql/test/typed_sql/insert/complex_constraints/complex_constraints_test.g.dart +++ b/typed_sql/test/typed_sql/insert/complex_constraints/complex_constraints_test.g.dart @@ -149,6 +149,24 @@ extension TableCompositePkItemExt on Table { values: [pkA.asExpr, pkB.asExpr, data.asExpr], ); + /// Insert row into the `compositePkItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `data`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required int pkA, + required String pkB, + required String data, + }) => insertValue(pkA: pkA, pkB: pkB, data: data) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(data: excluded.data)); + /// Bulk insert rows into the `compositePkItems` table. /// /// This method takes an `Iterable` and requires that you provide @@ -658,6 +676,31 @@ extension TableMultiUniqueItemExt on Table { values: [id?.asExpr, fieldA.asExpr, fieldB.asExpr, data.asExpr], ); + /// Insert row into the `multiUniqueItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `fieldA`, `fieldB`, `data`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String fieldA, + required int fieldB, + required String data, + }) => insertValue(id: id, fieldA: fieldA, fieldB: fieldB, data: data) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + fieldA: excluded.fieldA, + fieldB: excluded.fieldB, + data: excluded.data, + ), + ); + /// Bulk insert rows into the `multiUniqueItems` table. /// /// This method takes an `Iterable` and requires that you provide @@ -1243,6 +1286,31 @@ extension TableForeignKeyItemExt on Table { values: [id?.asExpr, refPkA.asExpr, refPkB.asExpr, data.asExpr], ); + /// Insert row into the `foreignKeyItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `refPkA`, `refPkB`, `data`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required int refPkA, + required String refPkB, + required String data, + }) => insertValue(id: id, refPkA: refPkA, refPkB: refPkB, data: data) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + refPkA: excluded.refPkA, + refPkB: excluded.refPkB, + data: excluded.data, + ), + ); + /// Bulk insert rows into the `foreignKeyItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/defaults/defaults_test.g.dart b/typed_sql/test/typed_sql/insert/defaults/defaults_test.g.dart index 9899fe51..fd44eb44 100644 --- a/typed_sql/test/typed_sql/insert/defaults/defaults_test.g.dart +++ b/typed_sql/test/typed_sql/insert/defaults/defaults_test.g.dart @@ -224,6 +224,49 @@ extension TableDefaultsItemExt on Table { ], ); + /// Insert row into the `defaultsItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `b`, `i`, `d`, `s`, `dtNow`, `dtEpoch`, `json`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + bool? b, + int? i, + double? d, + String? s, + DateTime? dtNow, + DateTime? dtEpoch, + JsonValue? json, + }) => + insertValue( + id: id, + b: b, + i: i, + d: d, + s: s, + dtNow: dtNow, + dtEpoch: dtEpoch, + json: json, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + b: excluded.b, + i: excluded.i, + d: excluded.d, + s: excluded.s, + dtNow: excluded.dtNow, + dtEpoch: excluded.dtEpoch, + json: excluded.json, + ), + ); + /// Bulk insert rows into the `defaultsItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/insert_value/insert_value_test.g.dart b/typed_sql/test/typed_sql/insert/insert_value/insert_value_test.g.dart index 21d1760d..7d5444cc 100644 --- a/typed_sql/test/typed_sql/insert/insert_value/insert_value_test.g.dart +++ b/typed_sql/test/typed_sql/insert/insert_value/insert_value_test.g.dart @@ -112,6 +112,21 @@ extension TableValueItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `valueItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `valueItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/insert_values_mapped/insert_values_mapped_test.g.dart b/typed_sql/test/typed_sql/insert/insert_values_mapped/insert_values_mapped_test.g.dart index 3fb234bb..dc91bea4 100644 --- a/typed_sql/test/typed_sql/insert/insert_values_mapped/insert_values_mapped_test.g.dart +++ b/typed_sql/test/typed_sql/insert/insert_values_mapped/insert_values_mapped_test.g.dart @@ -144,6 +144,37 @@ extension TableMappedItemExt on Table { values: [id?.asExpr, value.asExpr, count?.asExpr, nullableValue.asExpr], ); + /// Insert row into the `mappedItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, `count`, `nullableValue`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String value, + int? count, + String? nullableValue, + }) => + insertValue( + id: id, + value: value, + count: count, + nullableValue: nullableValue, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + value: excluded.value, + count: excluded.count, + nullableValue: excluded.nullableValue, + ), + ); + /// Bulk insert rows into the `mappedItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/insert_values_mapped_complex/insert_values_mapped_complex_test.g.dart b/typed_sql/test/typed_sql/insert/insert_values_mapped_complex/insert_values_mapped_complex_test.g.dart index 8b898c65..f6899181 100644 --- a/typed_sql/test/typed_sql/insert/insert_values_mapped_complex/insert_values_mapped_complex_test.g.dart +++ b/typed_sql/test/typed_sql/insert/insert_values_mapped_complex/insert_values_mapped_complex_test.g.dart @@ -211,6 +211,46 @@ extension TableComplexMappedItemExt on Table { ], ); + /// Insert row into the `complexMappedItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `s`, `dt`, `blob`, `custom`, `i`, `json`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + String? s, + DateTime? dt, + Uint8List? blob, + MyCustomType? custom, + int? i, + JsonValue? json, + }) => + insertValue( + id: id, + s: s, + dt: dt, + blob: blob, + custom: custom, + i: i, + json: json, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + s: excluded.s, + dt: excluded.dt, + blob: excluded.blob, + custom: excluded.custom, + i: excluded.i, + json: excluded.json, + ), + ); + /// Bulk insert rows into the `complexMappedItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/insert_values_mapped_conflict/insert_values_mapped_conflict_test.g.dart b/typed_sql/test/typed_sql/insert/insert_values_mapped_conflict/insert_values_mapped_conflict_test.g.dart index f75b7bc8..fe488d29 100644 --- a/typed_sql/test/typed_sql/insert/insert_values_mapped_conflict/insert_values_mapped_conflict_test.g.dart +++ b/typed_sql/test/typed_sql/insert/insert_values_mapped_conflict/insert_values_mapped_conflict_test.g.dart @@ -143,6 +143,26 @@ extension TableConflictMappedItemExt on Table { values: [complexId.asExpr, name.asExpr, value.asExpr], ); + /// Insert row into the `conflictMappedItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required int complexId, + required String name, + required int value, + }) => insertValue(complexId: complexId, name: name, value: value) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set(name: excluded.name, value: excluded.value), + ); + /// Bulk insert rows into the `conflictMappedItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/json_insert/json_insert_test.g.dart b/typed_sql/test/typed_sql/insert/json_insert/json_insert_test.g.dart index 406c6911..9bdb475a 100644 --- a/typed_sql/test/typed_sql/insert/json_insert/json_insert_test.g.dart +++ b/typed_sql/test/typed_sql/insert/json_insert/json_insert_test.g.dart @@ -115,6 +115,21 @@ extension TableJsonItemExt on Table { values: [id?.asExpr, data.asExpr], ); + /// Insert row into the `jsonItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `data`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required JsonValue data}) => + insertValue(id: id, data: data) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(data: excluded.data)); + /// Bulk insert rows into the `jsonItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/upsert/upsert_test.g.dart b/typed_sql/test/typed_sql/insert/upsert/upsert_test.g.dart index a4b5a87e..66eb1b77 100644 --- a/typed_sql/test/typed_sql/insert/upsert/upsert_test.g.dart +++ b/typed_sql/test/typed_sql/insert/upsert/upsert_test.g.dart @@ -158,6 +158,26 @@ extension TableSimpleItemExt on Table { values: [id?.asExpr, name.asExpr, value.asExpr], ); + /// Insert row into the `simpleItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String name, + required int value, + }) => insertValue(id: id, name: name, value: value) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set(name: excluded.name, value: excluded.value), + ); + /// Bulk insert rows into the `simpleItems` table. /// /// This method takes an `Iterable` and requires that you provide @@ -722,6 +742,39 @@ extension TableCompositeItemExt on Table { ], ); + /// Insert row into the `compositeItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstName`, `lastName`, `data`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required String partA, + required int partB, + required String firstName, + required String lastName, + required String data, + }) => + insertValue( + partA: partA, + partB: partB, + firstName: firstName, + lastName: lastName, + data: data, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + firstName: excluded.firstName, + lastName: excluded.lastName, + data: excluded.data, + ), + ); + /// Bulk insert rows into the `compositeItems` table. /// /// This method takes an `Iterable` and requires that you provide @@ -1309,6 +1362,27 @@ extension TableNullableUniqueItemExt on Table { values: [id?.asExpr, code.asExpr, description.asExpr], ); + /// Insert row into the `nullableUniqueItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `code`, `description`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + String? code, + required String description, + }) => insertValue(id: id, code: code, description: description) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(code: excluded.code, description: excluded.description), + ); + /// Bulk insert rows into the `nullableUniqueItems` table. /// /// This method takes an `Iterable` and requires that you provide @@ -1862,6 +1936,31 @@ extension TableSubQueryItemExt on Table { values: [id?.asExpr, tag.asExpr, refId.asExpr, count.asExpr], ); + /// Insert row into the `subQueryItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `tag`, `refId`, `count`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String tag, + required int refId, + required int count, + }) => insertValue(id: id, tag: tag, refId: refId, count: count) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + tag: excluded.tag, + refId: excluded.refId, + count: excluded.count, + ), + ); + /// Bulk insert rows into the `subQueryItems` table. /// /// This method takes an `Iterable` and requires that you provide @@ -2474,6 +2573,42 @@ extension TableComplexItemExt on Table { ], ); + /// Insert row into the `complexItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `doubleValue`, `boolValue`, `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required int id, + DateTime? createdAt, + required String name, + double? doubleValue, + bool? boolValue, + required int value, + }) => + insertValue( + id: id, + createdAt: createdAt, + name: name, + doubleValue: doubleValue, + boolValue: boolValue, + value: value, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + doubleValue: excluded.doubleValue, + boolValue: excluded.boolValue, + value: excluded.value, + ), + ); + /// Bulk insert rows into the `complexItems` table. /// /// This method takes an `Iterable` and requires that you provide @@ -3060,6 +3195,23 @@ extension TableCustomTypeItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `customTypeItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required MyCustomType value, + }) => insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `customTypeItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/upsert_basic/upsert_basic_test.g.dart b/typed_sql/test/typed_sql/insert/upsert_basic/upsert_basic_test.g.dart index 8135394f..0ba77097 100644 --- a/typed_sql/test/typed_sql/insert/upsert_basic/upsert_basic_test.g.dart +++ b/typed_sql/test/typed_sql/insert/upsert_basic/upsert_basic_test.g.dart @@ -136,6 +136,26 @@ extension TableBasicItemExt on Table { values: [id?.asExpr, name.asExpr, value.asExpr], ); + /// Insert row into the `basicItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String name, + required int value, + }) => insertValue(id: id, name: name, value: value) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set(name: excluded.name, value: excluded.value), + ); + /// Bulk insert rows into the `basicItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/upsert_complex/upsert_complex_test.g.dart b/typed_sql/test/typed_sql/insert/upsert_complex/upsert_complex_test.g.dart index 9ace532d..688c8a1e 100644 --- a/typed_sql/test/typed_sql/insert/upsert_complex/upsert_complex_test.g.dart +++ b/typed_sql/test/typed_sql/insert/upsert_complex/upsert_complex_test.g.dart @@ -215,6 +215,42 @@ extension TableComplexItemExt on Table { ], ); + /// Insert row into the `complexItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `doubleValue`, `boolValue`, `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required int id, + DateTime? createdAt, + required String name, + double? doubleValue, + bool? boolValue, + required int value, + }) => + insertValue( + id: id, + createdAt: createdAt, + name: name, + doubleValue: doubleValue, + boolValue: boolValue, + value: value, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + doubleValue: excluded.doubleValue, + boolValue: excluded.boolValue, + value: excluded.value, + ), + ); + /// Bulk insert rows into the `complexItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/upsert_customtype/upsert_customtype_test.g.dart b/typed_sql/test/typed_sql/insert/upsert_customtype/upsert_customtype_test.g.dart index 9dfca3e3..abc0059a 100644 --- a/typed_sql/test/typed_sql/insert/upsert_customtype/upsert_customtype_test.g.dart +++ b/typed_sql/test/typed_sql/insert/upsert_customtype/upsert_customtype_test.g.dart @@ -122,6 +122,23 @@ extension TableCustomTypeItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `customTypeItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required MyCustomType value, + }) => insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `customTypeItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/upsert_multi_conflict/upsert_multi_conflict_test.g.dart b/typed_sql/test/typed_sql/insert/upsert_multi_conflict/upsert_multi_conflict_test.g.dart index c0fa95b2..e9249f19 100644 --- a/typed_sql/test/typed_sql/insert/upsert_multi_conflict/upsert_multi_conflict_test.g.dart +++ b/typed_sql/test/typed_sql/insert/upsert_multi_conflict/upsert_multi_conflict_test.g.dart @@ -164,6 +164,31 @@ extension TableMultiItemExt on Table { values: [id?.asExpr, name.asExpr, email.asExpr, value.asExpr], ); + /// Insert row into the `multiItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `email`, `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String name, + required String email, + required int value, + }) => insertValue(id: id, name: name, email: email, value: value) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + email: excluded.email, + value: excluded.value, + ), + ); + /// Bulk insert rows into the `multiItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/upsert_negative/upsert_negative_test.g.dart b/typed_sql/test/typed_sql/insert/upsert_negative/upsert_negative_test.g.dart index 6bd8d8a3..b9206d11 100644 --- a/typed_sql/test/typed_sql/insert/upsert_negative/upsert_negative_test.g.dart +++ b/typed_sql/test/typed_sql/insert/upsert_negative/upsert_negative_test.g.dart @@ -115,6 +115,21 @@ extension TableNotNullItemExt on Table { values: [id?.asExpr, name.asExpr], ); + /// Insert row into the `notNullItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String name}) => + insertValue(id: id, name: name) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(name: excluded.name)); + /// Bulk insert rows into the `notNullItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/upsert_subquery/upsert_subquery_test.g.dart b/typed_sql/test/typed_sql/insert/upsert_subquery/upsert_subquery_test.g.dart index 3b76483c..2f4fcb56 100644 --- a/typed_sql/test/typed_sql/insert/upsert_subquery/upsert_subquery_test.g.dart +++ b/typed_sql/test/typed_sql/insert/upsert_subquery/upsert_subquery_test.g.dart @@ -118,6 +118,21 @@ extension TableSourceItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `sourceItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `sourceItems` table. /// /// This method takes an `Iterable` and requires that you provide @@ -602,6 +617,31 @@ extension TableSubQueryItemExt on Table { values: [id?.asExpr, tag.asExpr, refId.asExpr, count.asExpr], ); + /// Insert row into the `subQueryItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `tag`, `refId`, `count`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String tag, + required int refId, + required int count, + }) => insertValue(id: id, tag: tag, refId: refId, count: count) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + tag: excluded.tag, + refId: excluded.refId, + count: excluded.count, + ), + ); + /// Bulk insert rows into the `subQueryItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/insert/upsert_value/upsert_value_test.dart b/typed_sql/test/typed_sql/insert/upsert_value/upsert_value_test.dart new file mode 100644 index 00000000..dfec5f65 --- /dev/null +++ b/typed_sql/test/typed_sql/insert/upsert_value/upsert_value_test.dart @@ -0,0 +1,112 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import 'package:typed_sql/typed_sql.dart'; +import '../../testrunner.dart'; + +part 'upsert_value_test.g.dart'; + +abstract final class UpsertValueDatabase extends Schema { + Table get items; + + Table get links; +} + +@PrimaryKey(['id']) +abstract final class UpsertValueItem extends Row { + @AutoIncrement() + int get id; + + String get name; + + int get value; + + String? get note; +} + +@PrimaryKey(['a', 'b']) +abstract final class UpsertValueLink extends Row { + int get a; + int get b; +} + +void main() { + final r = TestRunner( + setup: (db) async { + await db.createTables(); + }, + ); + + r.addTest( + '.upsertValue() inserts when no conflict exists', + (db) async { + await db.items + .upsertValue(id: 1, name: 'A', value: 10, note: null) + .execute(); + final item = await db.items.byKey(1).fetch(); + check(item).isNotNull().name.equals('A'); + check(item).isNotNull().value.equals(10); + }, + skipMysql: 'mysql does not support ON CONFLICT clauses', + ); + + r.addTest( + '.upsertValue() updates non-primary-key fields on primary key conflict', + (db) async { + await db.items + .upsertValue(id: 1, name: 'A', value: 10, note: 'first') + .execute(); + await db.items + .upsertValue(id: 1, name: 'B', value: 20, note: 'second') + .execute(); + + final item = await db.items.byKey(1).fetch(); + check(item).isNotNull().name.equals('B'); + check(item).isNotNull().value.equals(20); + check(item).isNotNull().note.equals('second'); + }, + skipMysql: 'mysql does not support ON CONFLICT clauses', + ); + + r.addTest( + '.upsertValue() leaves the primary key untouched', + (db) async { + await db.items + .upsertValue(id: 1, name: 'A', value: 10, note: null) + .execute(); + await db.items + .upsertValue(id: 1, name: 'B', value: 20, note: null) + .execute(); + + final count = await db.items.count().fetch(); + check(count).equals(1); + }, + skipMysql: 'mysql does not support ON CONFLICT clauses', + ); + + r.addTest( + '.upsertValue() on all-primary-key row is a no-op update on conflict', + (db) async { + await db.links.upsertValue(a: 1, b: 2).execute(); + // Should not throw, even though there is nothing to update. + await db.links.upsertValue(a: 1, b: 2).execute(); + + final count = await db.links.count().fetch(); + check(count).equals(1); + }, + skipMysql: 'mysql does not support ON CONFLICT clauses', + ); + + r.run(); +} diff --git a/typed_sql/test/typed_sql/insert/upsert_value/upsert_value_test.g.dart b/typed_sql/test/typed_sql/insert/upsert_value/upsert_value_test.g.dart new file mode 100644 index 00000000..cd93995f --- /dev/null +++ b/typed_sql/test/typed_sql/insert/upsert_value/upsert_value_test.g.dart @@ -0,0 +1,1105 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'upsert_value_test.dart'; + +// ************************************************************************** +// Generator: _TypedSqlBuilder +// ************************************************************************** + +/// Extension methods for a [Database] operating on [UpsertValueDatabase]. +extension UpsertValueDatabaseSchema on Database { + static final _$tables = [ + _$UpsertValueItem._$table, + _$UpsertValueLink._$table, + ]; + + Table get items => + $ForGeneratedCode.declareTable(this, _$UpsertValueItem._$table); + + Table get links => + $ForGeneratedCode.declareTable(this, _$UpsertValueLink._$table); + + /// Create tables defined in [UpsertValueDatabase]. + /// + /// Calling this on an empty database will create the tables + /// defined in [UpsertValueDatabase]. In production it's often better to + /// use [createUpsertValueDatabaseTables] and manage migrations using + /// external tools. + /// + /// This method is mostly useful for testing. + /// + /// > [!WARNING] + /// > If the database is **not empty** behavior is undefined, most + /// > likely this operation will fail. + Future createTables() async => + $ForGeneratedCode.createTables(context: this, tables: _$tables); +} + +/// Get SQL [DDL statements][1] for tables defined in [UpsertValueDatabase]. +/// +/// This returns a SQL script with multiple DDL statements separated by `;` +/// using the specified [dialect]. +/// +/// Executing these statements in an empty database will create the tables +/// defined in [UpsertValueDatabase]. In practice, this method is often used for +/// printing the DDL statements, such that migrations can be managed by +/// external tools. +/// +/// [1]: https://en.wikipedia.org/wiki/Data_definition_language +String createUpsertValueDatabaseTables(SqlDialect dialect) => + $ForGeneratedCode.createTableSchema( + dialect: dialect, + tables: UpsertValueDatabaseSchema._$tables, + ); + +final class _$UpsertValueItem extends UpsertValueItem { + _$UpsertValueItem._(this.id, this.name, this.value, this.note); + + @override + final int id; + + @override + final String name; + + @override + final int value; + + @override + final String? note; + + static final _$table = $ForGeneratedCode.tableDefinition( + tableName: 'items', + columns: ['id', 'name', 'value', 'note'], + columnInfo: [ + $ForGeneratedCode.columnDefinition( + type: $ForGeneratedCode.integer, + isNotNull: true, + defaultValue: null, + autoIncrement: true, + overrides: [], + ), + $ForGeneratedCode.columnDefinition( + type: $ForGeneratedCode.text, + isNotNull: true, + defaultValue: null, + autoIncrement: false, + overrides: [], + ), + $ForGeneratedCode.columnDefinition( + type: $ForGeneratedCode.integer, + isNotNull: true, + defaultValue: null, + autoIncrement: false, + overrides: [], + ), + $ForGeneratedCode.columnDefinition( + type: $ForGeneratedCode.text, + isNotNull: false, + defaultValue: null, + autoIncrement: false, + overrides: [], + ), + ], + primaryKey: ['id'], + unique: >[], + foreignKeys: [], + indexes: [], + readRow: _$UpsertValueItem._$fromDatabase, + ); + + static UpsertValueItem? _$fromDatabase(RowReader row) { + final id = row.readInt(); + final name = row.readString(); + final value = row.readInt(); + final note = row.readString(); + if (id == null && name == null && value == null && note == null) { + return null; + } + return _$UpsertValueItem._(id!, name!, value!, note); + } + + @override + String toString() => + 'UpsertValueItem(id: "$id", name: "$name", value: "$value", note: "$note")'; +} + +/// Extension methods for table defined in [UpsertValueItem]. +extension TableUpsertValueItemExt on Table { + /// Insert row into the `items` table. + /// + /// Returns a [InsertSingle] statement on which `.execute` must be + /// called for the row to be inserted. + InsertSingle insert({ + Expr? id, + required Expr name, + required Expr value, + Expr? note, + }) => $ForGeneratedCode.insertInto( + table: this, + values: [id, name, value, note], + ); + + /// Insert row into the `items` table. + /// + /// Returns a [InsertSingle] statement on which `.execute` must be + /// called for the row to be inserted. + InsertSingle insertValue({ + int? id, + required String name, + required int value, + String? note, + }) => $ForGeneratedCode.insertInto( + table: this, + values: [id?.asExpr, name.asExpr, value.asExpr, note.asExpr], + ); + + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `value`, `note`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String name, + required int value, + String? note, + }) => insertValue(id: id, name: name, value: value, note: note) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + value: excluded.value, + note: excluded.note, + ), + ); + + /// Bulk insert rows into the `items` table. + /// + /// This method takes an `Iterable` and requires that you provide + /// a _mapping function_ from `T` to each column to be inserted. + /// + /// If a mapping function is omitted, the _default value_ will be + /// inserted, or `NULL` if column is nullable and as no default value. + /// To explicitely insert `NULL`, use a _mapping function_ that maps + /// `T` to `null`. + /// + /// > [!NOTE] + /// > This method aims utilize database specific bulk insertion logic + /// > to ensure good performance. Database adapters may pipeline bulk + /// > insertions through multiple statements inside a transaction. + /// + /// Returns a [Insert] statement on which `.execute` must be + /// called for the rows to be inserted. + Insert insertValuesMapped( + Iterable rows, { + int Function(T row)? id, + required String Function(T row) name, + required int Function(T row) value, + String? Function(T row)? note, + }) => $ForGeneratedCode.insertValuesMapped( + table: this, + rows: rows, + mappings: [id, name, value, note], + ); + + /// Delete a single row from the `items` table, specified by + /// _primary key_. + /// + /// Returns a [DeleteSingle] statement on which `.execute()` must be + /// called for the row to be deleted. + /// + /// To delete multiple rows, using `.where()` to filter which rows + /// should be deleted. If you wish to delete all rows, use + /// `.where((_) => toExpr(true)).delete()`. + DeleteSingle delete(int id) => + $ForGeneratedCode.deleteSingle(byKey(id), _$UpsertValueItem._$table); +} + +/// Extension methods for building queries against the `items` table. +extension QueryUpsertValueItemExt on Query<(Expr,)> { + /// Lookup a single row in `items` table using the _primary key_. + /// + /// Returns a [QuerySingle] object, which returns at-most one row, + /// when `.fetch()` is called. + QuerySingle<(Expr,)> byKey(int id) => + where((upsertValueItem) => upsertValueItem.id.equalsValue(id)).first; + + /// Update all rows in the `items` table matching this [Query]. + /// + /// The changes to be applied to each row matching this [Query] are + /// defined using the [updateBuilder], which is given an [Expr] + /// representation of the row being updated and a `set` function to + /// specify which fields should be updated. The result of the `set` + /// function should always be returned from the `updateBuilder`. + /// + /// Returns an [Update] statement on which `.execute()` must be called + /// for the rows to be updated. + /// + /// **Example:** decrementing `1` from the `value` field for each row + /// where `value > 0`. + /// ```dart + /// await db.mytable + /// .where((row) => row.value > toExpr(0)) + /// .update((row, set) => set( + /// value: row.value - toExpr(1), + /// )) + /// .execute(); + /// ``` + /// + /// > [!WARNING] + /// > The `updateBuilder` callback does not make the update, it builds + /// > the expressions for updating the rows. You should **never** invoke + /// > the `set` function more than once, and the result should always + /// > be returned immediately. + Update update( + UpdateSet Function( + Expr upsertValueItem, + UpdateSet Function({ + Expr id, + Expr name, + Expr value, + Expr note, + }) + set, + ) + updateBuilder, + ) => $ForGeneratedCode.update( + this, + _$UpsertValueItem._$table, + (upsertValueItem) => updateBuilder( + upsertValueItem, + ({ + Expr? id, + Expr? name, + Expr? value, + Expr? note, + }) => $ForGeneratedCode.buildUpdate([ + id, + name, + value, + note, + ]), + ), + ); + + /// Delete all rows in the `items` table matching this [Query]. + /// + /// Returns a [Delete] statement on which `.execute()` must be called + /// for the rows to be deleted. + Delete delete() => + $ForGeneratedCode.delete(this, _$UpsertValueItem._$table); +} + +/// Extension methods for building point queries against the `items` table. +extension QuerySingleUpsertValueItemExt + on QuerySingle<(Expr,)> { + /// Update the row (if any) in the `items` table matching this + /// [QuerySingle]. + /// + /// The changes to be applied to the row matching this [QuerySingle] are + /// defined using the [updateBuilder], which is given an [Expr] + /// representation of the row being updated and a `set` function to + /// specify which fields should be updated. The result of the `set` + /// function should always be returned from the `updateBuilder`. + /// + /// Returns an [UpdateSingle] statement on which `.execute()` must be + /// called for the row to be updated. The resulting statement will + /// **not** fail, if there are no rows matching this query exists. + /// + /// **Example:** decrementing `1` from the `value` field the row with + /// `id = 1`. + /// ```dart + /// await db.mytable + /// .byKey(1) + /// .update((row, set) => set( + /// value: row.value - toExpr(1), + /// )) + /// .execute(); + /// ``` + /// + /// > [!WARNING] + /// > The `updateBuilder` callback does not make the update, it builds + /// > the expressions for updating the rows. You should **never** invoke + /// > the `set` function more than once, and the result should always + /// > be returned immediately. + UpdateSingle update( + UpdateSet Function( + Expr upsertValueItem, + UpdateSet Function({ + Expr id, + Expr name, + Expr value, + Expr note, + }) + set, + ) + updateBuilder, + ) => $ForGeneratedCode.updateSingle( + this, + _$UpsertValueItem._$table, + (upsertValueItem) => updateBuilder( + upsertValueItem, + ({ + Expr? id, + Expr? name, + Expr? value, + Expr? note, + }) => $ForGeneratedCode.buildUpdate([ + id, + name, + value, + note, + ]), + ), + ); + + /// Delete the row (if any) in the `items` table matching this [QuerySingle]. + /// + /// Returns a [DeleteSingle] statement on which `.execute()` must be called + /// for the row to be deleted. The resulting statement will **not** + /// fail, if there are no rows matching this query exists. + DeleteSingle delete() => + $ForGeneratedCode.deleteSingle(this, _$UpsertValueItem._$table); +} + +/// Extension methods for expressions on a row in the `items` table. +extension ExpressionUpsertValueItemExt on Expr { + Expr get id => + $ForGeneratedCode.field(this, 0, $ForGeneratedCode.integer); + + Expr get name => + $ForGeneratedCode.field(this, 1, $ForGeneratedCode.text); + + Expr get value => + $ForGeneratedCode.field(this, 2, $ForGeneratedCode.integer); + + Expr get note => + $ForGeneratedCode.field(this, 3, $ForGeneratedCode.text); +} + +extension ExpressionNullableUpsertValueItemExt on Expr { + Expr get id => + $ForGeneratedCode.field(this, 0, $ForGeneratedCode.integer); + + Expr get name => + $ForGeneratedCode.field(this, 1, $ForGeneratedCode.text); + + Expr get value => + $ForGeneratedCode.field(this, 2, $ForGeneratedCode.integer); + + Expr get note => + $ForGeneratedCode.field(this, 3, $ForGeneratedCode.text); + + /// Check if the row is not `NULL`. + /// + /// This will check if _primary key_ fields in this row are `NULL`. + /// + /// If this is a reference lookup by subquery it might be more efficient + /// to check if the referencing field is `NULL`. + Expr isNotNull() => id.isNotNull(); + + /// Check if the row is `NULL`. + /// + /// This will check if _primary key_ fields in this row are `NULL`. + /// + /// If this is a reference lookup by subquery it might be more efficient + /// to check if the referencing field is `NULL`. + Expr isNull() => isNotNull().not(); +} + +/// `Table` conflict targets for use with `.onConflict`. +enum UpsertValueItemConflict { + /// Conflict with an existing row that has a matching primary key. + /// + /// Thus, the other row has matching values for: + /// `id`. + primaryKey(['id']); + + const UpsertValueItemConflict(this._fields); + + final List _fields; +} + +extension InsertUpsertValueItemExt on Insert { + /// Build an `INSERT` statement with an `ON CONFLICT` clause. + /// + /// The [target] argument specifies the _conflict target_ to be + /// handled. The _conflict target_ is always a `UNIQUE` constraint or + /// `PRIMARY KEY` constraint. + /// + /// If a row to be inserted violates the _conflict target_ constraint, + /// then the conflict action is triggered: + /// * `.doNothing()` to skip insertion of the new row, and, + /// * `.update((upsertValueItem, excluded, set) => set(...))` to + /// update the conflicting row. + /// + /// If a row to be inserted violates a constraint other than the one + /// specified in _conflict target_ then the entire `INSERT` statement + /// will fail. + /// + /// This is equivalent to `INSERT ... ON CONFLICT (...)` in SQL. + InsertOnConflict onConflict( + UpsertValueItemConflict target, + ) => $ForGeneratedCode.insertOnConflict(this, target._fields); +} + +extension InsertOnConflictUpsertValueItemExt + on InsertOnConflict { + /// Build an `INSERT` statement an [upsert-clause][1]. + /// + /// When a row to be inserted violates the `UNIQUE` or `PRIMARY KEY` + /// constraint previously specified as _conflict target_, the existing + /// row is updated using the expressions defined with the + /// [updateBuilder]. The [updateBuilder] is given 3 parameters: + /// * `upsertValueItem` an [Expr] representing the existing row in + /// the database, + /// * `excluded` an [Expr] representing the row to be inserted in the + /// database, and, + /// * `set` a function to specify which fields should be updated and + /// build the [UpdateSet]. + /// + /// The result of the `set` function should always be immediately + /// returned from the [updateBuilder]. + /// + /// **Example:** Insert a counter with `count = 2` or increment the + /// existing row, if a `PRIMARY KEY` conflict occurs. + /// ```dart + /// await db.counters.insertValue( + /// name: 'my-counter', // primary key + /// count: 2, + /// ) + /// .onConflict(.primaryKey) + /// .update((counter, excluded, set) => set( + /// count: counter.count + excluded.count, + /// )) + /// .execute(); + /// ``` + /// + /// This is equivalent to + /// `INSERT ... ON CONFLICT (...) UPDATE SET ...` in SQL. + /// + /// > [!WARNING] + /// > The `updateBuilder` callback does not make the update, it builds + /// > the expressions for updating the rows. You should **never** invoke + /// > the `set` function more than once, and the result should always + /// > be returned immediately. + /// + /// [1]: https://www.sqlite.org/lang_upsert.html + Upsert update( + UpdateSet Function( + Expr upsertValueItem, + Expr excluded, + UpdateSet Function({ + Expr id, + Expr name, + Expr value, + Expr note, + }) + set, + ) + updateBuilder, + ) => $ForGeneratedCode.updateOnConflict( + this, + (upsertValueItem, excluded) => updateBuilder( + upsertValueItem, + excluded, + ({ + Expr? id, + Expr? name, + Expr? value, + Expr? note, + }) => $ForGeneratedCode.buildUpdate([ + id, + name, + value, + note, + ]), + ), + ); +} + +extension InsertSingleUpsertValueItemExt on InsertSingle { + /// Build an `INSERT` statement with an `ON CONFLICT` clause. + /// + /// The [target] argument specifies the _conflict target_ to be + /// handled. The _conflict target_ is always a `UNIQUE` constraint or + /// `PRIMARY KEY` constraint. + /// + /// If a row to be inserted violates the _conflict target_ constraint, + /// then the conflict action is triggered: + /// * `.doNothing()` to skip insertion of the new row, and, + /// * `.update((upsertValueItem, excluded, set) => set(...))` to + /// update the conflicting row. + /// + /// If a row to be inserted violates a constraint other than the one + /// specified in _conflict target_ then the entire `INSERT` statement + /// will fail. + /// + /// This is equivalent to `INSERT ... ON CONFLICT (...)` in SQL. + InsertOnConflictSingle onConflict( + UpsertValueItemConflict target, + ) => $ForGeneratedCode.insertOnConflictSingle(this, target._fields); +} + +extension InsertOnConflictSingleUpsertValueItemExt + on InsertOnConflictSingle { + /// Build an `INSERT` statement an [upsert-clause][1]. + /// + /// When a row to be inserted violates the `UNIQUE` or `PRIMARY KEY` + /// constraint previously specified as _conflict target_, the existing + /// row is updated using the expressions defined with the + /// [updateBuilder]. The [updateBuilder] is given 3 parameters: + /// * `upsertValueItem` an [Expr] representing the existing row in + /// the database, + /// * `excluded` an [Expr] representing the row to be inserted in the + /// database, and, + /// * `set` a function to specify which fields should be updated and + /// build the [UpdateSet]. + /// + /// The result of the `set` function should always be immediately + /// returned from the [updateBuilder]. + /// + /// **Example:** Insert a counter with `count = 2` or increment the + /// existing row, if a `PRIMARY KEY` conflict occurs. + /// ```dart + /// await db.counters.insertValue( + /// name: 'my-counter', // primary key + /// count: 2, + /// ) + /// .onConflict(.primaryKey) + /// .update((counter, excluded, set) => set( + /// count: counter.count + excluded.count, + /// )) + /// .execute(); + /// ``` + /// + /// This is equivalent to + /// `INSERT ... ON CONFLICT (...) UPDATE SET ...` in SQL. + /// + /// > [!WARNING] + /// > The `updateBuilder` callback does not make the update, it builds + /// > the expressions for updating the rows. You should **never** invoke + /// > the `set` function more than once, and the result should always + /// > be returned immediately. + /// + /// [1]: https://www.sqlite.org/lang_upsert.html + UpsertSingle update( + UpdateSet Function( + Expr upsertValueItem, + Expr excluded, + UpdateSet Function({ + Expr id, + Expr name, + Expr value, + Expr note, + }) + set, + ) + updateBuilder, + ) => $ForGeneratedCode.updateOnConflictSingle( + this, + (upsertValueItem, excluded) => updateBuilder( + upsertValueItem, + excluded, + ({ + Expr? id, + Expr? name, + Expr? value, + Expr? note, + }) => $ForGeneratedCode.buildUpdate([ + id, + name, + value, + note, + ]), + ), + ); +} + +final class _$UpsertValueLink extends UpsertValueLink { + _$UpsertValueLink._(this.a, this.b); + + @override + final int a; + + @override + final int b; + + static final _$table = $ForGeneratedCode.tableDefinition( + tableName: 'links', + columns: ['a', 'b'], + columnInfo: [ + $ForGeneratedCode.columnDefinition( + type: $ForGeneratedCode.integer, + isNotNull: true, + defaultValue: null, + autoIncrement: false, + overrides: [], + ), + $ForGeneratedCode.columnDefinition( + type: $ForGeneratedCode.integer, + isNotNull: true, + defaultValue: null, + autoIncrement: false, + overrides: [], + ), + ], + primaryKey: ['a', 'b'], + unique: >[], + foreignKeys: [], + indexes: [], + readRow: _$UpsertValueLink._$fromDatabase, + ); + + static UpsertValueLink? _$fromDatabase(RowReader row) { + final a = row.readInt(); + final b = row.readInt(); + if (a == null && b == null) { + return null; + } + return _$UpsertValueLink._(a!, b!); + } + + @override + String toString() => 'UpsertValueLink(a: "$a", b: "$b")'; +} + +/// Extension methods for table defined in [UpsertValueLink]. +extension TableUpsertValueLinkExt on Table { + /// Insert row into the `links` table. + /// + /// Returns a [InsertSingle] statement on which `.execute` must be + /// called for the row to be inserted. + InsertSingle insert({ + required Expr a, + required Expr b, + }) => $ForGeneratedCode.insertInto(table: this, values: [a, b]); + + /// Insert row into the `links` table. + /// + /// Returns a [InsertSingle] statement on which `.execute` must be + /// called for the row to be inserted. + InsertSingle insertValue({required int a, required int b}) => + $ForGeneratedCode.insertInto(table: this, values: [a.asExpr, b.asExpr]); + + /// Insert row into the `links` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// nothing, as all fields are part of the _primary key_, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({required int a, required int b}) => + insertValue( + a: a, + b: b, + ).onConflict(.primaryKey).update((_, excluded, set) => set()); + + /// Bulk insert rows into the `links` table. + /// + /// This method takes an `Iterable` and requires that you provide + /// a _mapping function_ from `T` to each column to be inserted. + /// + /// If a mapping function is omitted, the _default value_ will be + /// inserted, or `NULL` if column is nullable and as no default value. + /// To explicitely insert `NULL`, use a _mapping function_ that maps + /// `T` to `null`. + /// + /// > [!NOTE] + /// > This method aims utilize database specific bulk insertion logic + /// > to ensure good performance. Database adapters may pipeline bulk + /// > insertions through multiple statements inside a transaction. + /// + /// Returns a [Insert] statement on which `.execute` must be + /// called for the rows to be inserted. + Insert insertValuesMapped( + Iterable rows, { + required int Function(T row) a, + required int Function(T row) b, + }) => $ForGeneratedCode.insertValuesMapped( + table: this, + rows: rows, + mappings: [a, b], + ); + + /// Delete a single row from the `links` table, specified by + /// _primary key_. + /// + /// Returns a [DeleteSingle] statement on which `.execute()` must be + /// called for the row to be deleted. + /// + /// To delete multiple rows, using `.where()` to filter which rows + /// should be deleted. If you wish to delete all rows, use + /// `.where((_) => toExpr(true)).delete()`. + DeleteSingle delete(int a, int b) => + $ForGeneratedCode.deleteSingle(byKey(a, b), _$UpsertValueLink._$table); +} + +/// Extension methods for building queries against the `links` table. +extension QueryUpsertValueLinkExt on Query<(Expr,)> { + /// Lookup a single row in `links` table using the _primary key_. + /// + /// Returns a [QuerySingle] object, which returns at-most one row, + /// when `.fetch()` is called. + QuerySingle<(Expr,)> byKey(int a, int b) => where( + (upsertValueLink) => + upsertValueLink.a.equalsValue(a) & upsertValueLink.b.equalsValue(b), + ).first; + + /// Update all rows in the `links` table matching this [Query]. + /// + /// The changes to be applied to each row matching this [Query] are + /// defined using the [updateBuilder], which is given an [Expr] + /// representation of the row being updated and a `set` function to + /// specify which fields should be updated. The result of the `set` + /// function should always be returned from the `updateBuilder`. + /// + /// Returns an [Update] statement on which `.execute()` must be called + /// for the rows to be updated. + /// + /// **Example:** decrementing `1` from the `value` field for each row + /// where `value > 0`. + /// ```dart + /// await db.mytable + /// .where((row) => row.value > toExpr(0)) + /// .update((row, set) => set( + /// value: row.value - toExpr(1), + /// )) + /// .execute(); + /// ``` + /// + /// > [!WARNING] + /// > The `updateBuilder` callback does not make the update, it builds + /// > the expressions for updating the rows. You should **never** invoke + /// > the `set` function more than once, and the result should always + /// > be returned immediately. + Update update( + UpdateSet Function( + Expr upsertValueLink, + UpdateSet Function({Expr a, Expr b}) set, + ) + updateBuilder, + ) => $ForGeneratedCode.update( + this, + _$UpsertValueLink._$table, + (upsertValueLink) => updateBuilder( + upsertValueLink, + ({Expr? a, Expr? b}) => + $ForGeneratedCode.buildUpdate([a, b]), + ), + ); + + /// Delete all rows in the `links` table matching this [Query]. + /// + /// Returns a [Delete] statement on which `.execute()` must be called + /// for the rows to be deleted. + Delete delete() => + $ForGeneratedCode.delete(this, _$UpsertValueLink._$table); +} + +/// Extension methods for building point queries against the `links` table. +extension QuerySingleUpsertValueLinkExt + on QuerySingle<(Expr,)> { + /// Update the row (if any) in the `links` table matching this + /// [QuerySingle]. + /// + /// The changes to be applied to the row matching this [QuerySingle] are + /// defined using the [updateBuilder], which is given an [Expr] + /// representation of the row being updated and a `set` function to + /// specify which fields should be updated. The result of the `set` + /// function should always be returned from the `updateBuilder`. + /// + /// Returns an [UpdateSingle] statement on which `.execute()` must be + /// called for the row to be updated. The resulting statement will + /// **not** fail, if there are no rows matching this query exists. + /// + /// **Example:** decrementing `1` from the `value` field the row with + /// `id = 1`. + /// ```dart + /// await db.mytable + /// .byKey(1) + /// .update((row, set) => set( + /// value: row.value - toExpr(1), + /// )) + /// .execute(); + /// ``` + /// + /// > [!WARNING] + /// > The `updateBuilder` callback does not make the update, it builds + /// > the expressions for updating the rows. You should **never** invoke + /// > the `set` function more than once, and the result should always + /// > be returned immediately. + UpdateSingle update( + UpdateSet Function( + Expr upsertValueLink, + UpdateSet Function({Expr a, Expr b}) set, + ) + updateBuilder, + ) => $ForGeneratedCode.updateSingle( + this, + _$UpsertValueLink._$table, + (upsertValueLink) => updateBuilder( + upsertValueLink, + ({Expr? a, Expr? b}) => + $ForGeneratedCode.buildUpdate([a, b]), + ), + ); + + /// Delete the row (if any) in the `links` table matching this [QuerySingle]. + /// + /// Returns a [DeleteSingle] statement on which `.execute()` must be called + /// for the row to be deleted. The resulting statement will **not** + /// fail, if there are no rows matching this query exists. + DeleteSingle delete() => + $ForGeneratedCode.deleteSingle(this, _$UpsertValueLink._$table); +} + +/// Extension methods for expressions on a row in the `links` table. +extension ExpressionUpsertValueLinkExt on Expr { + Expr get a => + $ForGeneratedCode.field(this, 0, $ForGeneratedCode.integer); + + Expr get b => + $ForGeneratedCode.field(this, 1, $ForGeneratedCode.integer); +} + +extension ExpressionNullableUpsertValueLinkExt on Expr { + Expr get a => + $ForGeneratedCode.field(this, 0, $ForGeneratedCode.integer); + + Expr get b => + $ForGeneratedCode.field(this, 1, $ForGeneratedCode.integer); + + /// Check if the row is not `NULL`. + /// + /// This will check if _primary key_ fields in this row are `NULL`. + /// + /// If this is a reference lookup by subquery it might be more efficient + /// to check if the referencing field is `NULL`. + Expr isNotNull() => a.isNotNull() & b.isNotNull(); + + /// Check if the row is `NULL`. + /// + /// This will check if _primary key_ fields in this row are `NULL`. + /// + /// If this is a reference lookup by subquery it might be more efficient + /// to check if the referencing field is `NULL`. + Expr isNull() => isNotNull().not(); +} + +/// `Table` conflict targets for use with `.onConflict`. +enum UpsertValueLinkConflict { + /// Conflict with an existing row that has a matching primary key. + /// + /// Thus, the other row has matching values for: + /// `a`, `b`. + primaryKey(['a', 'b']); + + const UpsertValueLinkConflict(this._fields); + + final List _fields; +} + +extension InsertUpsertValueLinkExt on Insert { + /// Build an `INSERT` statement with an `ON CONFLICT` clause. + /// + /// The [target] argument specifies the _conflict target_ to be + /// handled. The _conflict target_ is always a `UNIQUE` constraint or + /// `PRIMARY KEY` constraint. + /// + /// If a row to be inserted violates the _conflict target_ constraint, + /// then the conflict action is triggered: + /// * `.doNothing()` to skip insertion of the new row, and, + /// * `.update((upsertValueLink, excluded, set) => set(...))` to + /// update the conflicting row. + /// + /// If a row to be inserted violates a constraint other than the one + /// specified in _conflict target_ then the entire `INSERT` statement + /// will fail. + /// + /// This is equivalent to `INSERT ... ON CONFLICT (...)` in SQL. + InsertOnConflict onConflict( + UpsertValueLinkConflict target, + ) => $ForGeneratedCode.insertOnConflict(this, target._fields); +} + +extension InsertOnConflictUpsertValueLinkExt + on InsertOnConflict { + /// Build an `INSERT` statement an [upsert-clause][1]. + /// + /// When a row to be inserted violates the `UNIQUE` or `PRIMARY KEY` + /// constraint previously specified as _conflict target_, the existing + /// row is updated using the expressions defined with the + /// [updateBuilder]. The [updateBuilder] is given 3 parameters: + /// * `upsertValueLink` an [Expr] representing the existing row in + /// the database, + /// * `excluded` an [Expr] representing the row to be inserted in the + /// database, and, + /// * `set` a function to specify which fields should be updated and + /// build the [UpdateSet]. + /// + /// The result of the `set` function should always be immediately + /// returned from the [updateBuilder]. + /// + /// **Example:** Insert a counter with `count = 2` or increment the + /// existing row, if a `PRIMARY KEY` conflict occurs. + /// ```dart + /// await db.counters.insertValue( + /// name: 'my-counter', // primary key + /// count: 2, + /// ) + /// .onConflict(.primaryKey) + /// .update((counter, excluded, set) => set( + /// count: counter.count + excluded.count, + /// )) + /// .execute(); + /// ``` + /// + /// This is equivalent to + /// `INSERT ... ON CONFLICT (...) UPDATE SET ...` in SQL. + /// + /// > [!WARNING] + /// > The `updateBuilder` callback does not make the update, it builds + /// > the expressions for updating the rows. You should **never** invoke + /// > the `set` function more than once, and the result should always + /// > be returned immediately. + /// + /// [1]: https://www.sqlite.org/lang_upsert.html + Upsert update( + UpdateSet Function( + Expr upsertValueLink, + Expr excluded, + UpdateSet Function({Expr a, Expr b}) set, + ) + updateBuilder, + ) => $ForGeneratedCode.updateOnConflict( + this, + (upsertValueLink, excluded) => updateBuilder( + upsertValueLink, + excluded, + ({Expr? a, Expr? b}) => + $ForGeneratedCode.buildUpdate([a, b]), + ), + ); +} + +extension InsertSingleUpsertValueLinkExt on InsertSingle { + /// Build an `INSERT` statement with an `ON CONFLICT` clause. + /// + /// The [target] argument specifies the _conflict target_ to be + /// handled. The _conflict target_ is always a `UNIQUE` constraint or + /// `PRIMARY KEY` constraint. + /// + /// If a row to be inserted violates the _conflict target_ constraint, + /// then the conflict action is triggered: + /// * `.doNothing()` to skip insertion of the new row, and, + /// * `.update((upsertValueLink, excluded, set) => set(...))` to + /// update the conflicting row. + /// + /// If a row to be inserted violates a constraint other than the one + /// specified in _conflict target_ then the entire `INSERT` statement + /// will fail. + /// + /// This is equivalent to `INSERT ... ON CONFLICT (...)` in SQL. + InsertOnConflictSingle onConflict( + UpsertValueLinkConflict target, + ) => $ForGeneratedCode.insertOnConflictSingle(this, target._fields); +} + +extension InsertOnConflictSingleUpsertValueLinkExt + on InsertOnConflictSingle { + /// Build an `INSERT` statement an [upsert-clause][1]. + /// + /// When a row to be inserted violates the `UNIQUE` or `PRIMARY KEY` + /// constraint previously specified as _conflict target_, the existing + /// row is updated using the expressions defined with the + /// [updateBuilder]. The [updateBuilder] is given 3 parameters: + /// * `upsertValueLink` an [Expr] representing the existing row in + /// the database, + /// * `excluded` an [Expr] representing the row to be inserted in the + /// database, and, + /// * `set` a function to specify which fields should be updated and + /// build the [UpdateSet]. + /// + /// The result of the `set` function should always be immediately + /// returned from the [updateBuilder]. + /// + /// **Example:** Insert a counter with `count = 2` or increment the + /// existing row, if a `PRIMARY KEY` conflict occurs. + /// ```dart + /// await db.counters.insertValue( + /// name: 'my-counter', // primary key + /// count: 2, + /// ) + /// .onConflict(.primaryKey) + /// .update((counter, excluded, set) => set( + /// count: counter.count + excluded.count, + /// )) + /// .execute(); + /// ``` + /// + /// This is equivalent to + /// `INSERT ... ON CONFLICT (...) UPDATE SET ...` in SQL. + /// + /// > [!WARNING] + /// > The `updateBuilder` callback does not make the update, it builds + /// > the expressions for updating the rows. You should **never** invoke + /// > the `set` function more than once, and the result should always + /// > be returned immediately. + /// + /// [1]: https://www.sqlite.org/lang_upsert.html + UpsertSingle update( + UpdateSet Function( + Expr upsertValueLink, + Expr excluded, + UpdateSet Function({Expr a, Expr b}) set, + ) + updateBuilder, + ) => $ForGeneratedCode.updateOnConflictSingle( + this, + (upsertValueLink, excluded) => updateBuilder( + upsertValueLink, + excluded, + ({Expr? a, Expr? b}) => + $ForGeneratedCode.buildUpdate([a, b]), + ), + ); +} + +/// Extension methods for assertions on [UpsertValueItem] using +/// [`package:checks`][1]. +/// +/// [1]: https://pub.dev/packages/checks +extension UpsertValueItemChecks on Subject { + /// Create assertions on [UpsertValueItem.id]. + Subject get id => has((m) => m.id, 'id'); + + /// Create assertions on [UpsertValueItem.name]. + Subject get name => has((m) => m.name, 'name'); + + /// Create assertions on [UpsertValueItem.value]. + Subject get value => has((m) => m.value, 'value'); + + /// Create assertions on [UpsertValueItem.note]. + Subject get note => has((m) => m.note, 'note'); +} + +/// Extension methods for assertions on [UpsertValueLink] using +/// [`package:checks`][1]. +/// +/// [1]: https://pub.dev/packages/checks +extension UpsertValueLinkChecks on Subject { + /// Create assertions on [UpsertValueLink.a]. + Subject get a => has((m) => m.a, 'a'); + + /// Create assertions on [UpsertValueLink.b]. + Subject get b => has((m) => m.b, 'b'); +} diff --git a/typed_sql/test/typed_sql/join/join_model/join_model_test.g.dart b/typed_sql/test/typed_sql/join/join_model/join_model_test.g.dart index 240624cf..60c18207 100644 --- a/typed_sql/test/typed_sql/join/join_model/join_model_test.g.dart +++ b/typed_sql/test/typed_sql/join/join_model/join_model_test.g.dart @@ -137,6 +137,32 @@ extension TableEmployeeExt on Table { values: [employeeId?.asExpr, name.asExpr, departmentId.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `departmentId`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? employeeId, + required String name, + int? departmentId, + }) => + insertValue( + employeeId: employeeId, + name: name, + departmentId: departmentId, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, departmentId: excluded.departmentId), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide @@ -633,6 +659,27 @@ extension TableDepartmentExt on Table { values: [departmentId?.asExpr, name.asExpr, location.asExpr], ); + /// Insert row into the `departments` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `location`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? departmentId, + required String name, + required String location, + }) => insertValue(departmentId: departmentId, name: name, location: location) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, location: excluded.location), + ); + /// Bulk insert rows into the `departments` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/join/join_query/join_query_test.g.dart b/typed_sql/test/typed_sql/join/join_query/join_query_test.g.dart index 0e4e1241..0a3a2c9f 100644 --- a/typed_sql/test/typed_sql/join/join_query/join_query_test.g.dart +++ b/typed_sql/test/typed_sql/join/join_query/join_query_test.g.dart @@ -137,6 +137,32 @@ extension TableEmployeeExt on Table { values: [employeeId?.asExpr, name.asExpr, departmentId.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `departmentId`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? employeeId, + required String name, + int? departmentId, + }) => + insertValue( + employeeId: employeeId, + name: name, + departmentId: departmentId, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, departmentId: excluded.departmentId), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide @@ -633,6 +659,27 @@ extension TableDepartmentExt on Table { values: [departmentId?.asExpr, name.asExpr, location.asExpr], ); + /// Insert row into the `departments` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `location`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? departmentId, + required String name, + required String location, + }) => insertValue(departmentId: departmentId, name: name, location: location) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, location: excluded.location), + ); + /// Bulk insert rows into the `departments` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/join/join_using/join_using_test.g.dart b/typed_sql/test/typed_sql/join/join_using/join_using_test.g.dart index 4f523e00..79211f27 100644 --- a/typed_sql/test/typed_sql/join/join_using/join_using_test.g.dart +++ b/typed_sql/test/typed_sql/join/join_using/join_using_test.g.dart @@ -146,6 +146,32 @@ extension TableEmployeeExt on Table { values: [employeeId?.asExpr, name.asExpr, departmentId.asExpr], ); + /// Insert row into the `employees` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `departmentId`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? employeeId, + required String name, + int? departmentId, + }) => + insertValue( + employeeId: employeeId, + name: name, + departmentId: departmentId, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, departmentId: excluded.departmentId), + ); + /// Bulk insert rows into the `employees` table. /// /// This method takes an `Iterable` and requires that you provide @@ -695,6 +721,27 @@ extension TableDepartmentExt on Table { values: [departmentId?.asExpr, name.asExpr, location.asExpr], ); + /// Insert row into the `departments` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `location`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? departmentId, + required String name, + required String location, + }) => insertValue(departmentId: departmentId, name: name, location: location) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, location: excluded.location), + ); + /// Bulk insert rows into the `departments` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/join/nullable_on/nullable_on_test.g.dart b/typed_sql/test/typed_sql/join/nullable_on/nullable_on_test.g.dart index 650fc481..cdfa0fd8 100644 --- a/typed_sql/test/typed_sql/join/nullable_on/nullable_on_test.g.dart +++ b/typed_sql/test/typed_sql/join/nullable_on/nullable_on_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({required int id, bool? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/json/deep_extraction/deep_extraction_test.g.dart b/typed_sql/test/typed_sql/json/deep_extraction/deep_extraction_test.g.dart index 92feae06..fdacbda8 100644 --- a/typed_sql/test/typed_sql/json/deep_extraction/deep_extraction_test.g.dart +++ b/typed_sql/test/typed_sql/json/deep_extraction/deep_extraction_test.g.dart @@ -128,6 +128,27 @@ extension TableProductExt on Table { values: [id?.asExpr, name.asExpr, metadata.asExpr], ); + /// Insert row into the `products` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `metadata`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String name, + required JsonValue metadata, + }) => insertValue(id: id, name: name, metadata: metadata) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, metadata: excluded.metadata), + ); + /// Bulk insert rows into the `products` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/json/null_handling/null_handling_test.g.dart b/typed_sql/test/typed_sql/json/null_handling/null_handling_test.g.dart index 630c8a0a..9f6b9687 100644 --- a/typed_sql/test/typed_sql/json/null_handling/null_handling_test.g.dart +++ b/typed_sql/test/typed_sql/json/null_handling/null_handling_test.g.dart @@ -128,6 +128,27 @@ extension TableProductExt on Table { values: [id?.asExpr, name.asExpr, metadata?.asExpr], ); + /// Insert row into the `products` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `metadata`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String name, + JsonValue? metadata, + }) => insertValue(id: id, name: name, metadata: metadata) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(name: excluded.name, metadata: excluded.metadata), + ); + /// Bulk insert rows into the `products` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/key/autoincrement/autoincrement_test.g.dart b/typed_sql/test/typed_sql/key/autoincrement/autoincrement_test.g.dart index aa954aad..aa3545da 100644 --- a/typed_sql/test/typed_sql/key/autoincrement/autoincrement_test.g.dart +++ b/typed_sql/test/typed_sql/key/autoincrement/autoincrement_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/key/composite_key/composite_key_test.g.dart b/typed_sql/test/typed_sql/key/composite_key/composite_key_test.g.dart index dc527f83..5a48fc86 100644 --- a/typed_sql/test/typed_sql/key/composite_key/composite_key_test.g.dart +++ b/typed_sql/test/typed_sql/key/composite_key/composite_key_test.g.dart @@ -133,6 +133,24 @@ extension TableItemExt on Table { values: [id.asExpr, name.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required int id, + required String name, + String? value, + }) => insertValue(id: id, name: name, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/key/text_key/text_key_test.g.dart b/typed_sql/test/typed_sql/key/text_key/text_key_test.g.dart index cc3cf948..9511f80b 100644 --- a/typed_sql/test/typed_sql/key/text_key/text_key_test.g.dart +++ b/typed_sql/test/typed_sql/key/text_key/text_key_test.g.dart @@ -120,6 +120,23 @@ extension TableItemExt on Table { values: [key.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required String key, + required String value, + }) => insertValue(key: key, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/nullable/blob/blob_test.g.dart b/typed_sql/test/typed_sql/nullable/blob/blob_test.g.dart index 3e707a9a..cecdc396 100644 --- a/typed_sql/test/typed_sql/nullable/blob/blob_test.g.dart +++ b/typed_sql/test/typed_sql/nullable/blob/blob_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, Uint8List? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/nullable/nullable_boolean/nullable_boolean_test.g.dart b/typed_sql/test/typed_sql/nullable/nullable_boolean/nullable_boolean_test.g.dart index 02658dd2..0a5efd75 100644 --- a/typed_sql/test/typed_sql/nullable/nullable_boolean/nullable_boolean_test.g.dart +++ b/typed_sql/test/typed_sql/nullable/nullable_boolean/nullable_boolean_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, bool? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, bool? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/nullable/nullable_datetime/nullable_datetime_test.g.dart b/typed_sql/test/typed_sql/nullable/nullable_datetime/nullable_datetime_test.g.dart index 58f29ee6..b4c952b6 100644 --- a/typed_sql/test/typed_sql/nullable/nullable_datetime/nullable_datetime_test.g.dart +++ b/typed_sql/test/typed_sql/nullable/nullable_datetime/nullable_datetime_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, DateTime? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/nullable/nullable_integer/nullable_integer_test.g.dart b/typed_sql/test/typed_sql/nullable/nullable_integer/nullable_integer_test.g.dart index aaf32a3f..005f7404 100644 --- a/typed_sql/test/typed_sql/nullable/nullable_integer/nullable_integer_test.g.dart +++ b/typed_sql/test/typed_sql/nullable/nullable_integer/nullable_integer_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, int? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, int? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/nullable/nullable_json/nullable_json_test.g.dart b/typed_sql/test/typed_sql/nullable/nullable_json/nullable_json_test.g.dart index 3b242e92..08700b07 100644 --- a/typed_sql/test/typed_sql/nullable/nullable_json/nullable_json_test.g.dart +++ b/typed_sql/test/typed_sql/nullable/nullable_json/nullable_json_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, JsonValue? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/nullable/nullable_real/nullable_real_test.g.dart b/typed_sql/test/typed_sql/nullable/nullable_real/nullable_real_test.g.dart index fe42d0a6..8cabe638 100644 --- a/typed_sql/test/typed_sql/nullable/nullable_real/nullable_real_test.g.dart +++ b/typed_sql/test/typed_sql/nullable/nullable_real/nullable_real_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, double? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, double? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/nullable/nullable_text/nullable_text_test.g.dart b/typed_sql/test/typed_sql/nullable/nullable_text/nullable_text_test.g.dart index c39e8329..be27bfbd 100644 --- a/typed_sql/test/typed_sql/nullable/nullable_text/nullable_text_test.g.dart +++ b/typed_sql/test/typed_sql/nullable/nullable_text/nullable_text_test.g.dart @@ -106,6 +106,21 @@ extension TableItemExt on Table { InsertSingle insertValue({int? id, String? value}) => $ForGeneratedCode .insertInto(table: this, values: [id?.asExpr, value.asExpr]); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, String? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/order_by/order_by_composite/order_by_composite_test.g.dart b/typed_sql/test/typed_sql/order_by/order_by_composite/order_by_composite_test.g.dart index 2dfc0545..937d87a6 100644 --- a/typed_sql/test/typed_sql/order_by/order_by_composite/order_by_composite_test.g.dart +++ b/typed_sql/test/typed_sql/order_by/order_by_composite/order_by_composite_test.g.dart @@ -166,6 +166,40 @@ extension TableItemExt on Table { ], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `text`, `real`, `timestamp`, `integer`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? id, + required String text, + required double real, + required DateTime timestamp, + int? integer, + }) => + insertValue( + id: id, + text: text, + real: real, + timestamp: timestamp, + integer: integer, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + text: excluded.text, + real: excluded.real, + timestamp: excluded.timestamp, + integer: excluded.integer, + ), + ); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/overrides/dialect_specific_ddl/dialect_specific_ddl_test.g.dart b/typed_sql/test/typed_sql/overrides/dialect_specific_ddl/dialect_specific_ddl_test.g.dart index 45098676..4ea61f8f 100644 --- a/typed_sql/test/typed_sql/overrides/dialect_specific_ddl/dialect_specific_ddl_test.g.dart +++ b/typed_sql/test/typed_sql/overrides/dialect_specific_ddl/dialect_specific_ddl_test.g.dart @@ -224,6 +224,40 @@ extension TableDialectItemExt on Table { ], ); + /// Insert row into the `dialectItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `category`, `status`, `itemColor`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? itemId, + required String name, + required String category, + required String status, + required Color itemColor, + }) => + insertValue( + itemId: itemId, + name: name, + category: category, + status: status, + itemColor: itemColor, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + category: excluded.category, + status: excluded.status, + itemColor: excluded.itemColor, + ), + ); + /// Bulk insert rows into the `dialectItems` table. /// /// This method takes an `Iterable` and requires that you provide @@ -793,6 +827,21 @@ extension TableDialectLogExt on Table { values: [logId?.asExpr, refItemId.asExpr], ); + /// Insert row into the `dialectLogs` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `refItemId`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? logId, required int refItemId}) => + insertValue(logId: logId, refItemId: refItemId) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(refItemId: excluded.refItemId)); + /// Bulk insert rows into the `dialectLogs` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/overrides/hierarchical_naming/hierarchical_naming_test.g.dart b/typed_sql/test/typed_sql/overrides/hierarchical_naming/hierarchical_naming_test.g.dart index 8db2faf4..f6af2479 100644 --- a/typed_sql/test/typed_sql/overrides/hierarchical_naming/hierarchical_naming_test.g.dart +++ b/typed_sql/test/typed_sql/overrides/hierarchical_naming/hierarchical_naming_test.g.dart @@ -218,6 +218,40 @@ extension TableHierarchyUserExt on Table { ], ); + /// Insert row into the `hierarchyUsers` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstName`, `lastName`, `emailAddress`, `userColor`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? userId, + required String firstName, + required String lastName, + required String emailAddress, + required Color userColor, + }) => + insertValue( + userId: userId, + firstName: firstName, + lastName: lastName, + emailAddress: emailAddress, + userColor: userColor, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + firstName: excluded.firstName, + lastName: excluded.lastName, + emailAddress: excluded.emailAddress, + userColor: excluded.userColor, + ), + ); + /// Bulk insert rows into the `hierarchyUsers` table. /// /// This method takes an `Iterable` and requires that you provide @@ -818,6 +852,34 @@ extension TableHierarchyProfileExt on Table { values: [profileId?.asExpr, userRefId.asExpr, profileType.asExpr], ); + /// Insert row into the `hierarchyProfiles` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `userRefId`, `profileType`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? profileId, + required int userRefId, + required String profileType, + }) => + insertValue( + profileId: profileId, + userRefId: userRefId, + profileType: profileType, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + userRefId: excluded.userRefId, + profileType: excluded.profileType, + ), + ); + /// Bulk insert rows into the `hierarchyProfiles` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/overrides/legacy_names/legacy_names_test.g.dart b/typed_sql/test/typed_sql/overrides/legacy_names/legacy_names_test.g.dart index b723d17b..f44624af 100644 --- a/typed_sql/test/typed_sql/overrides/legacy_names/legacy_names_test.g.dart +++ b/typed_sql/test/typed_sql/overrides/legacy_names/legacy_names_test.g.dart @@ -233,6 +233,42 @@ extension TableLegacyUserExt on Table { ], ); + /// Insert row into the `users` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstName`, `lastName`, `email`, `color`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required int tenantId, + required int userId, + required String firstName, + required String lastName, + required String email, + required Color color, + }) => + insertValue( + tenantId: tenantId, + userId: userId, + firstName: firstName, + lastName: lastName, + email: email, + color: color, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + firstName: excluded.firstName, + lastName: excluded.lastName, + email: excluded.email, + color: excluded.color, + ), + ); + /// Bulk insert rows into the `users` table. /// /// This method takes an `Iterable` and requires that you provide @@ -856,6 +892,28 @@ extension TableLegacyCommentExt on Table { values: [commentId?.asExpr, tId.asExpr, uId.asExpr, text.asExpr], ); + /// Insert row into the `comments` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `tId`, `uId`, `text`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? commentId, + required int tId, + required int uId, + required String text, + }) => insertValue(commentId: commentId, tId: tId, uId: uId, text: text) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(tId: excluded.tId, uId: excluded.uId, text: excluded.text), + ); + /// Bulk insert rows into the `comments` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/overrides/schema_snake_case/schema_snake_case_test.g.dart b/typed_sql/test/typed_sql/overrides/schema_snake_case/schema_snake_case_test.g.dart index 05a4a91c..245c220f 100644 --- a/typed_sql/test/typed_sql/overrides/schema_snake_case/schema_snake_case_test.g.dart +++ b/typed_sql/test/typed_sql/overrides/schema_snake_case/schema_snake_case_test.g.dart @@ -226,6 +226,40 @@ extension TableSnakeUserExt on Table { ], ); + /// Insert row into the `snakeUsers` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstName`, `lastName`, `emailAddress`, `favoriteColor`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? userId, + required String firstName, + required String lastName, + required String emailAddress, + required Color favoriteColor, + }) => + insertValue( + userId: userId, + firstName: firstName, + lastName: lastName, + emailAddress: emailAddress, + favoriteColor: favoriteColor, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + firstName: excluded.firstName, + lastName: excluded.lastName, + emailAddress: excluded.emailAddress, + favoriteColor: excluded.favoriteColor, + ), + ); + /// Bulk insert rows into the `snakeUsers` table. /// /// This method takes an `Iterable` and requires that you provide @@ -824,6 +858,34 @@ extension TableSnakeProfileExt on Table { values: [profileId?.asExpr, userRefId.asExpr, profileType.asExpr], ); + /// Insert row into the `snakeProfiles` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `userRefId`, `profileType`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? profileId, + required int userRefId, + required String profileType, + }) => + insertValue( + profileId: profileId, + userRefId: userRefId, + profileType: profileType, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + userRefId: excluded.userRefId, + profileType: excluded.profileType, + ), + ); + /// Bulk insert rows into the `snakeProfiles` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/references/nullable_reference/nullable_reference_test.g.dart b/typed_sql/test/typed_sql/references/nullable_reference/nullable_reference_test.g.dart index 657bc95c..d3fc2a9d 100644 --- a/typed_sql/test/typed_sql/references/nullable_reference/nullable_reference_test.g.dart +++ b/typed_sql/test/typed_sql/references/nullable_reference/nullable_reference_test.g.dart @@ -142,6 +142,34 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, name.asExpr, favoriteBookId.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `name`, `favoriteBookId`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? authorId, + required String name, + int? favoriteBookId, + }) => + insertValue( + authorId: authorId, + name: name, + favoriteBookId: favoriteBookId, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + name: excluded.name, + favoriteBookId: excluded.favoriteBookId, + ), + ); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -823,6 +851,40 @@ extension TableBookExt on Table { ], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `editorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + required int authorId, + int? editorId, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + editorId: editorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + editorId: excluded.editorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/references/references_id_as/references_id_as_test.g.dart b/typed_sql/test/typed_sql/references/references_id_as/references_id_as_test.g.dart index 34e66bb3..ffa36882 100644 --- a/typed_sql/test/typed_sql/references/references_id_as/references_id_as_test.g.dart +++ b/typed_sql/test/typed_sql/references/references_id_as/references_id_as_test.g.dart @@ -133,6 +133,28 @@ extension TableAuthorExt on Table { values: [authorId?.asExpr, firstname.asExpr, lastname.asExpr], ); + /// Insert row into the `authors` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstname`, `lastname`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? authorId, + required String firstname, + required String lastname, + }) => + insertValue(authorId: authorId, firstname: firstname, lastname: lastname) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(firstname: excluded.firstname, lastname: excluded.lastname), + ); + /// Bulk insert rows into the `authors` table. /// /// This method takes an `Iterable` and requires that you provide @@ -709,6 +731,37 @@ extension TableBookExt on Table { values: [bookId?.asExpr, title.asExpr, authorId.asExpr, stock.asExpr], ); + /// Insert row into the `books` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `title`, `authorId`, `stock`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? bookId, + required String title, + required int authorId, + required int stock, + }) => + insertValue( + bookId: bookId, + title: title, + authorId: authorId, + stock: stock, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + title: excluded.title, + authorId: excluded.authorId, + stock: excluded.stock, + ), + ); + /// Bulk insert rows into the `books` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/subquery/as_subquery_model/as_subquery_model_test.g.dart b/typed_sql/test/typed_sql/subquery/as_subquery_model/as_subquery_model_test.g.dart index f39debdc..8566d105 100644 --- a/typed_sql/test/typed_sql/subquery/as_subquery_model/as_subquery_model_test.g.dart +++ b/typed_sql/test/typed_sql/subquery/as_subquery_model/as_subquery_model_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/subquery/exists_model/exists_model_test.g.dart b/typed_sql/test/typed_sql/subquery/exists_model/exists_model_test.g.dart index 4c06e519..e343fed1 100644 --- a/typed_sql/test/typed_sql/subquery/exists_model/exists_model_test.g.dart +++ b/typed_sql/test/typed_sql/subquery/exists_model/exists_model_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/transact/key_conflict/key_conflict_test.g.dart b/typed_sql/test/typed_sql/transact/key_conflict/key_conflict_test.g.dart index 975bbc1e..fecdd4bd 100644 --- a/typed_sql/test/typed_sql/transact/key_conflict/key_conflict_test.g.dart +++ b/typed_sql/test/typed_sql/transact/key_conflict/key_conflict_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/transact/nested_basic/nested_basic_test.g.dart b/typed_sql/test/typed_sql/transact/nested_basic/nested_basic_test.g.dart index c392e4a1..e529ca98 100644 --- a/typed_sql/test/typed_sql/transact/nested_basic/nested_basic_test.g.dart +++ b/typed_sql/test/typed_sql/transact/nested_basic/nested_basic_test.g.dart @@ -140,6 +140,34 @@ extension TableAccountExt on Table { values: [accountId?.asExpr, accountNumber.asExpr, balance?.asExpr], ); + /// Insert row into the `accounts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `accountNumber`, `balance`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? accountId, + required String accountNumber, + double? balance, + }) => + insertValue( + accountId: accountId, + accountNumber: accountNumber, + balance: balance, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + accountNumber: excluded.accountNumber, + balance: excluded.balance, + ), + ); + /// Bulk insert rows into the `accounts` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/transact/nested_complex/nested_complex_test.g.dart b/typed_sql/test/typed_sql/transact/nested_complex/nested_complex_test.g.dart index f35aab7c..a5e071a0 100644 --- a/typed_sql/test/typed_sql/transact/nested_complex/nested_complex_test.g.dart +++ b/typed_sql/test/typed_sql/transact/nested_complex/nested_complex_test.g.dart @@ -140,6 +140,34 @@ extension TableAccountExt on Table { values: [accountId?.asExpr, accountNumber.asExpr, balance?.asExpr], ); + /// Insert row into the `accounts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `accountNumber`, `balance`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? accountId, + required String accountNumber, + double? balance, + }) => + insertValue( + accountId: accountId, + accountNumber: accountNumber, + balance: balance, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + accountNumber: excluded.accountNumber, + balance: excluded.balance, + ), + ); + /// Bulk insert rows into the `accounts` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/types/datetime/datetime_test.g.dart b/typed_sql/test/typed_sql/types/datetime/datetime_test.g.dart index 82bccdcb..d9c14493 100644 --- a/typed_sql/test/typed_sql/types/datetime/datetime_test.g.dart +++ b/typed_sql/test/typed_sql/types/datetime/datetime_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required DateTime value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/unique/composite_unique/composite_unique_test.g.dart b/typed_sql/test/typed_sql/unique/composite_unique/composite_unique_test.g.dart index c90f9d25..5feec2eb 100644 --- a/typed_sql/test/typed_sql/unique/composite_unique/composite_unique_test.g.dart +++ b/typed_sql/test/typed_sql/unique/composite_unique/composite_unique_test.g.dart @@ -149,6 +149,32 @@ extension TableUserExt on Table { values: [accountId?.asExpr, firstName.asExpr, lastName.asExpr], ); + /// Insert row into the `users` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `firstName`, `lastName`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? accountId, + required String firstName, + required String lastName, + }) => + insertValue( + accountId: accountId, + firstName: firstName, + lastName: lastName, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => + set(firstName: excluded.firstName, lastName: excluded.lastName), + ); + /// Bulk insert rows into the `users` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/unique/customdata/customdata_test.g.dart b/typed_sql/test/typed_sql/unique/customdata/customdata_test.g.dart index 152503c1..11a91800 100644 --- a/typed_sql/test/typed_sql/unique/customdata/customdata_test.g.dart +++ b/typed_sql/test/typed_sql/unique/customdata/customdata_test.g.dart @@ -132,6 +132,23 @@ extension TableCustomDataItemExt on Table { values: [id.asExpr, stringVal.asExpr], ); + /// Insert row into the `customDataItems` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `stringVal`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + required CustomIntType id, + required CustomStringType stringVal, + }) => insertValue(id: id, stringVal: stringVal) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(stringVal: excluded.stringVal)); + /// Bulk insert rows into the `customDataItems` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/unique/types/unique_boolean/unique_boolean_test.g.dart b/typed_sql/test/typed_sql/unique/types/unique_boolean/unique_boolean_test.g.dart index d0e159de..38089069 100644 --- a/typed_sql/test/typed_sql/unique/types/unique_boolean/unique_boolean_test.g.dart +++ b/typed_sql/test/typed_sql/unique/types/unique_boolean/unique_boolean_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required bool value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/unique/types/unique_integer/unique_integer_test.g.dart b/typed_sql/test/typed_sql/unique/types/unique_integer/unique_integer_test.g.dart index d06e09ac..0894ecbc 100644 --- a/typed_sql/test/typed_sql/unique/types/unique_integer/unique_integer_test.g.dart +++ b/typed_sql/test/typed_sql/unique/types/unique_integer/unique_integer_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required int value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/unique/types/unique_real/unique_real_test.g.dart b/typed_sql/test/typed_sql/unique/types/unique_real/unique_real_test.g.dart index 39ac428e..90baa50c 100644 --- a/typed_sql/test/typed_sql/unique/types/unique_real/unique_real_test.g.dart +++ b/typed_sql/test/typed_sql/unique/types/unique_real/unique_real_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required double value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/unique/types/unique_text/unique_text_test.g.dart b/typed_sql/test/typed_sql/unique/types/unique_text/unique_text_test.g.dart index 6b0cdb91..6bf0de3d 100644 --- a/typed_sql/test/typed_sql/unique/types/unique_text/unique_text_test.g.dart +++ b/typed_sql/test/typed_sql/unique/types/unique_text/unique_text_test.g.dart @@ -121,6 +121,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required String value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/unique/types/unique_zero_real/unique_zero_real_test.g.dart b/typed_sql/test/typed_sql/unique/types/unique_zero_real/unique_zero_real_test.g.dart index 12c7d5a9..bb30b9f8 100644 --- a/typed_sql/test/typed_sql/unique/types/unique_zero_real/unique_zero_real_test.g.dart +++ b/typed_sql/test/typed_sql/unique/types/unique_zero_real/unique_zero_real_test.g.dart @@ -114,6 +114,21 @@ extension TableItemExt on Table { values: [id?.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({int? id, required double value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/unique/unique_model/unique_model_test.g.dart b/typed_sql/test/typed_sql/unique/unique_model/unique_model_test.g.dart index 55ce958f..60af8606 100644 --- a/typed_sql/test/typed_sql/unique/unique_model/unique_model_test.g.dart +++ b/typed_sql/test/typed_sql/unique/unique_model/unique_model_test.g.dart @@ -140,6 +140,34 @@ extension TableAccountExt on Table { values: [accountId?.asExpr, accountNumber.asExpr, balance?.asExpr], ); + /// Insert row into the `accounts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `accountNumber`, `balance`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? accountId, + required String accountNumber, + double? balance, + }) => + insertValue( + accountId: accountId, + accountNumber: accountNumber, + balance: balance, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + accountNumber: excluded.accountNumber, + balance: excluded.balance, + ), + ); + /// Bulk insert rows into the `accounts` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/unique/unique_nullable/unique_nullable_test.g.dart b/typed_sql/test/typed_sql/unique/unique_nullable/unique_nullable_test.g.dart index fc209e11..9223ee19 100644 --- a/typed_sql/test/typed_sql/unique/unique_nullable/unique_nullable_test.g.dart +++ b/typed_sql/test/typed_sql/unique/unique_nullable/unique_nullable_test.g.dart @@ -140,6 +140,34 @@ extension TableAccountExt on Table { values: [accountId?.asExpr, accountNumber.asExpr, balance?.asExpr], ); + /// Insert row into the `accounts` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `accountNumber`, `balance`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({ + int? accountId, + String? accountNumber, + double? balance, + }) => + insertValue( + accountId: accountId, + accountNumber: accountNumber, + balance: balance, + ) + .onConflict(.primaryKey) + .update( + (_, excluded, set) => set( + accountNumber: excluded.accountNumber, + balance: excluded.balance, + ), + ); + /// Bulk insert rows into the `accounts` table. /// /// This method takes an `Iterable` and requires that you provide diff --git a/typed_sql/test/typed_sql/where/nullable_bool/nullable_bool_where_test.g.dart b/typed_sql/test/typed_sql/where/nullable_bool/nullable_bool_where_test.g.dart index 44ae8797..15016214 100644 --- a/typed_sql/test/typed_sql/where/nullable_bool/nullable_bool_where_test.g.dart +++ b/typed_sql/test/typed_sql/where/nullable_bool/nullable_bool_where_test.g.dart @@ -109,6 +109,21 @@ extension TableItemExt on Table { values: [id.asExpr, value.asExpr], ); + /// Insert row into the `items` table, or update the + /// existing row if it conflicts with the _primary key_. + /// + /// This is a shorthand for calling `.insertValue(...)` followed by + /// `.onConflict(.primaryKey)` and `.update(...)` to overwrite + /// the fields `value`, + /// with the values given, leaving the _primary key_ untouched. + /// + /// Returns an [UpsertSingle] statement on which `.execute()` must be + /// called for the row to be inserted or updated. + UpsertSingle upsertValue({required int id, bool? value}) => + insertValue(id: id, value: value) + .onConflict(.primaryKey) + .update((_, excluded, set) => set(value: excluded.value)); + /// Bulk insert rows into the `items` table. /// /// This method takes an `Iterable` and requires that you provide