test: Add a DST and tests reproducing found failures (#110)

Co-authored-by: Marcelo Soares <marcelo.me.soares@gmail.com>
This commit is contained in:
Kasper Overgård Nielsen 2026-09-04 18:09:20 +02:00 • committed by GitHub
commit c78af247fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
40 changed files with 22825 additions and 184 deletions

View file

@ -0,0 +1,106 @@
{
"__className__": "serverpod.DatabaseMigration",
"actions": [
{
"__className__": "serverpod.DatabaseMigrationAction",
"type": "createTable",
"createTable": {
"__className__": "serverpod.TableDefinition",
"name": "unique_cascade_child",
"dartName": "UniqueCascadeChild",
"module": "serverpod_offline_sync_test",
"schema": "public",
"columns": [
{
"__className__": "serverpod.ColumnDefinition",
"name": "id",
"fieldName": "id",
"columnType": 7,
"isNullable": false,
"columnDefault": "random_v7",
"dartType": "UuidValue?"
},
{
"__className__": "serverpod.ColumnDefinition",
"name": "scopeId",
"fieldName": "scopeId",
"columnType": 6,
"isNullable": true,
"dartType": "int?"
},
{
"__className__": "serverpod.ColumnDefinition",
"name": "name",
"fieldName": "name",
"columnType": 0,
"isNullable": false,
"dartType": "String"
},
{
"__className__": "serverpod.ColumnDefinition",
"name": "parentId",
"fieldName": "parentId",
"columnType": 7,
"isNullable": true,
"dartType": "UuidValue?"
}
],
"foreignKeys": [
{
"__className__": "serverpod.ForeignKeyDefinition",
"constraintName": "unique_cascade_child_fk_0",
"columns": [
"scopeId"
],
"referenceTable": "crdt_scopes",
"referenceTableSchema": "public",
"referenceColumns": [
"id"
],
"onUpdate": 3,
"onDelete": 4
},
{
"__className__": "serverpod.ForeignKeyDefinition",
"constraintName": "unique_cascade_child_fk_1",
"columns": [
"parentId"
],
"referenceTable": "person",
"referenceTableSchema": "public",
"referenceColumns": [
"id"
],
"onUpdate": 3,
"onDelete": 4,
"deferrable": "initiallyDeferred"
}
],
"indexes": [
{
"__className__": "serverpod.IndexDefinition",
"indexName": "unique_cascade_child__scopeId__name__unique_idx",
"elements": [
{
"__className__": "serverpod.IndexElementDefinition",
"type": 0,
"definition": "scopeId"
},
{
"__className__": "serverpod.IndexElementDefinition",
"type": 0,
"definition": "name"
}
],
"type": "btree",
"isUnique": true,
"isPrimary": false
}
],
"managed": true
}
}
],
"warnings": [],
"migrationApiVersion": 1
}

View file

@ -7,6 +7,7 @@ import 'package:serverpod_database/serverpod_database.dart';
part '20260703114649226/migration.dart';
part '20260824213459360/migration.dart';
part '20260831202219662/migration.dart';
part '20260901174859443/migration.dart';
/// Migration registry for the client-side database.
class MigrationRegistry {
@ -16,6 +17,7 @@ class MigrationRegistry {
_Migration20260703114649226(),
_Migration20260824213459360(),
_Migration20260831202219662(),
_Migration20260901174859443(),
];
/// List of all client-side database migration versions.

View file

@ -37,6 +37,7 @@ import 'town.dart' as _iytblq2r;
import 'types.dart' as _iwxwszsz;
import 'types_enum.dart' as _ire5m5mj;
import 'unique.dart' as _ivpwn84u;
import 'unique_cascade_child.dart' as _ixnh46zn;
import 'unique_composite.dart' as _iv4klbbv;
import 'unique_discriminator.dart' as _ixfoa5hm;
import 'unique_no_release.dart' as _i91ey4jd;
@ -62,6 +63,7 @@ export 'town.dart';
export 'types.dart';
export 'types_enum.dart';
export 'unique.dart';
export 'unique_cascade_child.dart';
export 'unique_composite.dart';
export 'unique_discriminator.dart';
export 'unique_no_release.dart';
@ -1267,6 +1269,82 @@ class Protocol extends _isd.DatabaseSerializationManager {
],
managed: true,
),
_isd.TableDefinition(
name: 'unique_cascade_child',
dartName: 'UniqueCascadeChild',
schema: 'public',
module: 'serverpod_offline_sync_test',
columns: [
_isd.ColumnDefinition(
name: 'id',
columnType: _isd.ColumnType.uuid,
isNullable: false,
dartType: 'UuidValue?',
columnDefault: 'random_v7',
),
_isd.ColumnDefinition(
name: 'scopeId',
columnType: _isd.ColumnType.bigint,
isNullable: true,
dartType: 'int?',
),
_isd.ColumnDefinition(
name: 'name',
columnType: _isd.ColumnType.text,
isNullable: false,
dartType: 'String',
),
_isd.ColumnDefinition(
name: 'parentId',
columnType: _isd.ColumnType.uuid,
isNullable: true,
dartType: 'UuidValue?',
),
],
foreignKeys: [
_isd.ForeignKeyDefinition(
constraintName: 'unique_cascade_child_fk_0',
columns: ['scopeId'],
referenceTable: 'crdt_scopes',
referenceTableSchema: 'public',
referenceColumns: ['id'],
onUpdate: _isd.ForeignKeyAction.noAction,
onDelete: _isd.ForeignKeyAction.cascade,
matchType: null,
),
_isd.ForeignKeyDefinition(
constraintName: 'unique_cascade_child_fk_1',
columns: ['parentId'],
referenceTable: 'person',
referenceTableSchema: 'public',
referenceColumns: ['id'],
onUpdate: _isd.ForeignKeyAction.noAction,
onDelete: _isd.ForeignKeyAction.cascade,
matchType: null,
deferrable: _isd.DeferrableConstraint.initiallyDeferred,
),
],
indexes: [
_isd.IndexDefinition(
indexName: 'unique_cascade_child__scopeId__name__unique_idx',
tableSpace: null,
elements: [
_isd.IndexElementDefinition(
type: _isd.IndexElementDefinitionType.column,
definition: 'scopeId',
),
_isd.IndexElementDefinition(
type: _isd.IndexElementDefinitionType.column,
definition: 'name',
),
],
type: 'btree',
isUnique: true,
isPrimary: false,
),
],
managed: true,
),
_isd.TableDefinition(
name: 'unique_composite',
dartName: 'UniqueComposite',
@ -1693,6 +1771,9 @@ class Protocol extends _isd.DatabaseSerializationManager {
if (t == _ivpwn84u.Unique) {
return _ivpwn84u.Unique.fromJson(data) as T;
}
if (t == _ixnh46zn.UniqueCascadeChild) {
return _ixnh46zn.UniqueCascadeChild.fromJson(data) as T;
}
if (t == _iv4klbbv.UniqueComposite) {
return _iv4klbbv.UniqueComposite.fromJson(data) as T;
}
@ -1796,6 +1877,10 @@ class Protocol extends _isd.DatabaseSerializationManager {
if (t == _isc.getType<_ivpwn84u.Unique?>()) {
return (data != null ? _ivpwn84u.Unique.fromJson(data) : null) as T;
}
if (t == _isc.getType<_ixnh46zn.UniqueCascadeChild?>()) {
return (data != null ? _ixnh46zn.UniqueCascadeChild.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_iv4klbbv.UniqueComposite?>()) {
return (data != null ? _iv4klbbv.UniqueComposite.fromJson(data) : null)
as T;
@ -1882,6 +1967,7 @@ class Protocol extends _isd.DatabaseSerializationManager {
_iwxwszsz.Types => 'Types',
_ire5m5mj.TypesEnum => 'TypesEnum',
_ivpwn84u.Unique => 'Unique',
_ixnh46zn.UniqueCascadeChild => 'UniqueCascadeChild',
_iv4klbbv.UniqueComposite => 'UniqueComposite',
_ixfoa5hm.UniqueDiscriminator => 'UniqueDiscriminator',
_i91ey4jd.UniqueNoRelease => 'UniqueNoRelease',
@ -1944,6 +2030,8 @@ class Protocol extends _isd.DatabaseSerializationManager {
return 'TypesEnum';
case _ivpwn84u.Unique():
return 'Unique';
case _ixnh46zn.UniqueCascadeChild():
return 'UniqueCascadeChild';
case _iv4klbbv.UniqueComposite():
return 'UniqueComposite';
case _ixfoa5hm.UniqueDiscriminator():
@ -2036,6 +2124,9 @@ class Protocol extends _isd.DatabaseSerializationManager {
if (dataClassName == 'Unique') {
return deserialize<_ivpwn84u.Unique>(data['data']);
}
if (dataClassName == 'UniqueCascadeChild') {
return deserialize<_ixnh46zn.UniqueCascadeChild>(data['data']);
}
if (dataClassName == 'UniqueComposite') {
return deserialize<_iv4klbbv.UniqueComposite>(data['data']);
}
@ -2129,6 +2220,8 @@ class Protocol extends _isd.DatabaseSerializationManager {
return _iwxwszsz.Types.t;
case _ivpwn84u.Unique:
return _ivpwn84u.Unique.t;
case _ixnh46zn.UniqueCascadeChild:
return _ixnh46zn.UniqueCascadeChild.t;
case _iv4klbbv.UniqueComposite:
return _iv4klbbv.UniqueComposite.t;
case _ixfoa5hm.UniqueDiscriminator:

View file

@ -0,0 +1,747 @@
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
/* To generate run: "serverpod generate" */
// ignore_for_file: implementation_imports
// ignore_for_file: library_private_types_in_public_api
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: public_member_api_docs
// ignore_for_file: type_literal_in_constant_pattern
// ignore_for_file: use_super_parameters
// ignore_for_file: invalid_use_of_internal_member
// ignore_for_file: dead_code, no_leading_underscores_for_library_prefixes
// ignore_for_file: unnecessary_null_comparison
import 'package:serverpod_client/serverpod_client.dart' as _isc;
import 'package:serverpod_database/serverpod_database.dart' as _isd;
import 'package:serverpod_offline_sync_test_client/src/protocol/protocol.dart'
as _imkb9kra;
import 'person.dart' as _iensfz4m;
abstract class UniqueCascadeChild
implements _isd.TableRow<_isc.UuidValue?>, _isc.ProtocolSerialization {
UniqueCascadeChild._({
this.id,
this.scopeId,
required this.name,
this.parentId,
this.parent,
});
factory UniqueCascadeChild({
_isc.UuidValue? id,
int? scopeId,
required String name,
_isc.UuidValue? parentId,
_iensfz4m.Person? parent,
}) = _UniqueCascadeChildImpl;
factory UniqueCascadeChild.fromJson(Map<String, dynamic> jsonSerialization) {
return UniqueCascadeChild(
id: jsonSerialization['id'] == null
? null
: _isc.UuidValueJsonExtension.fromJson(jsonSerialization['id']),
scopeId: jsonSerialization['scopeId'] as int?,
name: jsonSerialization['name'] as String,
parentId: jsonSerialization['parentId'] == null
? null
: _isc.UuidValueJsonExtension.fromJson(jsonSerialization['parentId']),
parent: jsonSerialization['parent'] == null
? null
: _imkb9kra.Protocol().deserialize<_iensfz4m.Person>(
jsonSerialization['parent'],
),
);
}
static final t = UniqueCascadeChildTable();
static const db = UniqueCascadeChildRepository._();
@override
_isc.UuidValue? id;
/// The scope owning this row. Maintained by the sync engine.
int? scopeId;
String name;
_isc.UuidValue? parentId;
_iensfz4m.Person? parent;
@override
_isd.Table<_isc.UuidValue?> get table => t;
/// Returns a shallow copy of this [UniqueCascadeChild]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
UniqueCascadeChild copyWith({
_isc.UuidValue? id,
int? scopeId,
String? name,
_isc.UuidValue? parentId,
_iensfz4m.Person? parent,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'UniqueCascadeChild',
if (id != null) 'id': id?.toJson(),
if (scopeId != null) 'scopeId': scopeId,
'name': name,
if (parentId != null) 'parentId': parentId?.toJson(),
if (parent != null) 'parent': parent?.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'UniqueCascadeChild',
if (id != null) 'id': id?.toJson(),
if (scopeId != null) 'scopeId': scopeId,
'name': name,
if (parentId != null) 'parentId': parentId?.toJson(),
if (parent != null) 'parent': parent?.toJsonForProtocol(),
};
}
static UniqueCascadeChildInclude include({_iensfz4m.PersonInclude? parent}) {
return UniqueCascadeChildInclude._(parent: parent);
}
static UniqueCascadeChildIncludeList includeList({
_isd.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
int? limit,
int? offset,
_isd.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_isd.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
UniqueCascadeChildInclude? include,
}) {
return UniqueCascadeChildIncludeList._(
where: where,
limit: limit,
offset: offset,
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
include: include,
);
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _Undefined {}
class _UniqueCascadeChildImpl extends UniqueCascadeChild {
_UniqueCascadeChildImpl({
_isc.UuidValue? id,
int? scopeId,
required String name,
_isc.UuidValue? parentId,
_iensfz4m.Person? parent,
}) : super._(
id: id,
scopeId: scopeId,
name: name,
parentId: parentId,
parent: parent,
);
/// Returns a shallow copy of this [UniqueCascadeChild]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
UniqueCascadeChild copyWith({
Object? id = _Undefined,
Object? scopeId = _Undefined,
String? name,
Object? parentId = _Undefined,
Object? parent = _Undefined,
}) {
return UniqueCascadeChild(
id: id is _isc.UuidValue? ? id : this.id,
scopeId: scopeId is int? ? scopeId : this.scopeId,
name: name ?? this.name,
parentId: parentId is _isc.UuidValue? ? parentId : this.parentId,
parent: parent is _iensfz4m.Person? ? parent : this.parent?.copyWith(),
);
}
}
class UniqueCascadeChildUpdateTable
extends _isd.UpdateTable<UniqueCascadeChildTable> {
UniqueCascadeChildUpdateTable(super.table);
_isd.ColumnValue<int, int> scopeId(int? value) => _isd.ColumnValue(
table.scopeId,
value,
);
_isd.ColumnValue<String, String> name(String value) => _isd.ColumnValue(
table.name,
value,
);
_isd.ColumnValue<_isc.UuidValue, _isc.UuidValue> parentId(
_isc.UuidValue? value,
) => _isd.ColumnValue(
table.parentId,
value,
);
}
class UniqueCascadeChildTable extends _isd.Table<_isc.UuidValue?> {
UniqueCascadeChildTable({super.tableRelation})
: super(tableName: 'unique_cascade_child') {
updateTable = UniqueCascadeChildUpdateTable(this);
scopeId = _isd.ColumnInt(
'scopeId',
this,
);
name = _isd.ColumnString(
'name',
this,
);
parentId = _isd.ColumnUuid(
'parentId',
this,
);
}
late final UniqueCascadeChildUpdateTable updateTable;
/// The scope owning this row. Maintained by the sync engine.
late final _isd.ColumnInt scopeId;
late final _isd.ColumnString name;
late final _isd.ColumnUuid parentId;
_iensfz4m.PersonTable? _parent;
_iensfz4m.PersonTable get parent {
if (_parent != null) return _parent!;
_parent = _isd.createRelationTable(
relationFieldName: 'parent',
field: UniqueCascadeChild.t.parentId,
foreignField: _iensfz4m.Person.t.id,
tableRelation: tableRelation,
createTable: (foreignTableRelation) =>
_iensfz4m.PersonTable(tableRelation: foreignTableRelation),
);
return _parent!;
}
@override
List<_isd.Column> get columns => [
id,
scopeId,
name,
parentId,
];
@override
_isd.Table? getRelationTable(String relationField) {
if (relationField == 'parent') {
return parent;
}
return null;
}
}
class UniqueCascadeChildInclude extends _isd.IncludeObject {
UniqueCascadeChildInclude._({_iensfz4m.PersonInclude? parent}) {
_parent = parent;
}
_iensfz4m.PersonInclude? _parent;
@override
Map<String, _isd.Include?> get includes => {'parent': _parent};
@override
_isd.Table<_isc.UuidValue?> get table => UniqueCascadeChild.t;
}
class UniqueCascadeChildIncludeList extends _isd.IncludeList {
UniqueCascadeChildIncludeList._({
_isd.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
super.limit,
super.offset,
super.orderBy,
super.orderByList,
super.include,
}) {
super.where = where?.call(UniqueCascadeChild.t);
}
@override
Map<String, _isd.Include?> get includes => include?.includes ?? {};
@override
_isd.Table<_isc.UuidValue?> get table => UniqueCascadeChild.t;
}
class UniqueCascadeChildRepository {
const UniqueCascadeChildRepository._();
final attachRow = const UniqueCascadeChildAttachRowRepository._();
final detachRow = const UniqueCascadeChildDetachRowRepository._();
/// Returns a list of [UniqueCascadeChild]s matching the given query parameters.
///
/// Use [where] to specify which items to include in the return value.
/// If none is specified, all items will be returned.
///
/// To specify the order of the items use [orderBy] or [orderByList]
/// when sorting by multiple columns.
///
/// The maximum number of items can be set by [limit]. If no limit is set,
/// all items matching the query will be returned.
///
/// [offset] defines how many items to skip, after which [limit] (or all)
/// items are read from the database.
///
/// ```dart
/// var persons = await Persons.db.find(
/// session,
/// where: (t) => t.lastName.equals('Jones'),
/// orderBy: (t) => t.firstName,
/// limit: 100,
/// );
/// ```
Future<List<UniqueCascadeChild>> find(
_isd.DatabaseSession session, {
_isd.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
int? limit,
int? offset,
_isd.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_isd.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_isd.Transaction? transaction,
UniqueCascadeChildInclude? include,
_isd.LockMode? lockMode,
_isd.LockBehavior? lockBehavior,
}) async {
return session.db.find<UniqueCascadeChild>(
where: where?.call(UniqueCascadeChild.t),
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
limit: limit,
offset: offset,
transaction: transaction,
include: include,
lockMode: lockMode,
lockBehavior: lockBehavior,
);
}
/// Returns the first matching [UniqueCascadeChild] matching the given query parameters.
///
/// Use [where] to specify which items to include in the return value.
/// If none is specified, all items will be returned.
///
/// To specify the order use [orderBy] or [orderByList]
/// when sorting by multiple columns.
///
/// [offset] defines how many items to skip, after which the next one will be picked.
///
/// ```dart
/// var youngestPerson = await Persons.db.findFirstRow(
/// session,
/// where: (t) => t.lastName.equals('Jones'),
/// orderBy: (t) => t.age,
/// );
/// ```
Future<UniqueCascadeChild?> findFirstRow(
_isd.DatabaseSession session, {
_isd.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
int? offset,
_isd.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_isd.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_isd.Transaction? transaction,
UniqueCascadeChildInclude? include,
_isd.LockMode? lockMode,
_isd.LockBehavior? lockBehavior,
}) async {
return session.db.findFirstRow<UniqueCascadeChild>(
where: where?.call(UniqueCascadeChild.t),
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
offset: offset,
transaction: transaction,
include: include,
lockMode: lockMode,
lockBehavior: lockBehavior,
);
}
/// Finds a single [UniqueCascadeChild] by its [id] or null if no such row exists.
Future<UniqueCascadeChild?> findById(
_isd.DatabaseSession session,
_isc.UuidValue id, {
_isd.Transaction? transaction,
UniqueCascadeChildInclude? include,
_isd.LockMode? lockMode,
_isd.LockBehavior? lockBehavior,
}) async {
return session.db.findById<UniqueCascadeChild>(
id,
transaction: transaction,
include: include,
lockMode: lockMode,
lockBehavior: lockBehavior,
);
}
/// Inserts all [UniqueCascadeChild]s in the list and returns the inserted rows.
///
/// The returned [UniqueCascadeChild]s will have their `id` fields set.
///
/// This is an atomic operation, meaning that if one of the rows fails to
/// insert, none of the rows will be inserted.
///
/// If [ignoreConflicts] is set to `true`, rows that conflict with existing
/// rows are silently skipped, and only the successfully inserted rows are
/// returned.
///
/// If [noReturn] is set to `true`, the inserted rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> insert(
_isd.DatabaseSession session,
List<UniqueCascadeChild> rows, {
_isd.Transaction? transaction,
bool ignoreConflicts = false,
bool noReturn = false,
}) async {
return session.db.insert<UniqueCascadeChild>(
rows,
transaction: transaction,
ignoreConflicts: ignoreConflicts,
noReturn: noReturn,
);
}
/// Inserts a single [UniqueCascadeChild] and returns the inserted row.
///
/// The returned [UniqueCascadeChild] will have its `id` field set.
Future<UniqueCascadeChild> insertRow(
_isd.DatabaseSession session,
UniqueCascadeChild row, {
_isd.Transaction? transaction,
}) async {
return session.db.insertRow<UniqueCascadeChild>(
row,
transaction: transaction,
);
}
/// Upserts all [UniqueCascadeChild]s in the list and returns the resulting rows.
///
/// If a row conflicts on the given [conflictColumns], the existing row is
/// updated with the new values. Otherwise, a new row is inserted.
///
/// If [updateColumns] is provided, only those columns will be updated on
/// conflict. If null, all non-conflict, non-id columns are updated.
///
/// If [updateWhere] is provided, the update only applies to rows matching the
/// given expression. Conflicting rows that don't match are skipped and not
/// returned, so the resulting list may be shorter than [rows].
///
/// The returned [UniqueCascadeChild]s will have their `id` fields set.
///
/// This is an atomic operation, meaning that if one of the rows fails,
/// none of the rows will be affected.
///
/// If [noReturn] is set to `true`, the resulting rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> upsert(
_isd.DatabaseSession session,
List<UniqueCascadeChild> rows, {
required _isd.ColumnSelections<UniqueCascadeChildTable> conflictColumns,
_isd.ColumnSelections<UniqueCascadeChildTable>? updateColumns,
_isd.WhereExpressionBuilder<UniqueCascadeChildTable>? updateWhere,
_isd.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.upsert<UniqueCascadeChild>(
rows,
conflictColumns: conflictColumns(UniqueCascadeChild.t),
updateColumns: updateColumns?.call(UniqueCascadeChild.t),
updateWhere: updateWhere?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Upserts a single [UniqueCascadeChild] and returns the resulting row.
///
/// If the row conflicts on the given [conflictColumns], the existing row is
/// updated. Otherwise, a new row is inserted.
///
/// If [updateColumns] is provided, only those columns will be updated on
/// conflict. If null, all non-conflict, non-id columns are updated.
///
/// If [updateWhere] is provided, the update only applies when the existing
/// row matches the expression. Returns `null` if no row was affected — for
/// example when [updateWhere] does not match the conflicting row.
///
/// The returned [UniqueCascadeChild] will have its `id` field set.
Future<UniqueCascadeChild?> upsertRow(
_isd.DatabaseSession session,
UniqueCascadeChild row, {
required _isd.ColumnSelections<UniqueCascadeChildTable> conflictColumns,
_isd.ColumnSelections<UniqueCascadeChildTable>? updateColumns,
_isd.WhereExpressionBuilder<UniqueCascadeChildTable>? updateWhere,
_isd.Transaction? transaction,
}) async {
return session.db.upsertRow<UniqueCascadeChild>(
row,
conflictColumns: conflictColumns(UniqueCascadeChild.t),
updateColumns: updateColumns?.call(UniqueCascadeChild.t),
updateWhere: updateWhere?.call(UniqueCascadeChild.t),
transaction: transaction,
);
}
/// Updates all [UniqueCascadeChild]s in the list and returns the updated rows. If
/// [columns] is provided, only those columns will be updated. Defaults to
/// all columns.
/// This is an atomic operation, meaning that if one of the rows fails to
/// update, none of the rows will be updated.
///
/// If [noReturn] is set to `true`, the updated rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> update(
_isd.DatabaseSession session,
List<UniqueCascadeChild> rows, {
_isd.ColumnSelections<UniqueCascadeChildTable>? columns,
_isd.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.update<UniqueCascadeChild>(
rows,
columns: columns?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Updates a single [UniqueCascadeChild]. The row needs to have its id set.
/// Optionally, a list of [columns] can be provided to only update those
/// columns. Defaults to all columns.
Future<UniqueCascadeChild> updateRow(
_isd.DatabaseSession session,
UniqueCascadeChild row, {
_isd.ColumnSelections<UniqueCascadeChildTable>? columns,
_isd.Transaction? transaction,
}) async {
return session.db.updateRow<UniqueCascadeChild>(
row,
columns: columns?.call(UniqueCascadeChild.t),
transaction: transaction,
);
}
/// Updates a single [UniqueCascadeChild] by its [id] with the specified [columnValues].
/// Returns the updated row or null if no row with the given id exists.
Future<UniqueCascadeChild?> updateById(
_isd.DatabaseSession session,
_isc.UuidValue id, {
required _isd.ColumnValueListBuilder<UniqueCascadeChildUpdateTable>
columnValues,
_isd.Transaction? transaction,
}) async {
return session.db.updateById<UniqueCascadeChild>(
id,
columnValues: columnValues(UniqueCascadeChild.t.updateTable),
transaction: transaction,
);
}
/// Updates all [UniqueCascadeChild]s matching the [where] expression with the specified [columnValues].
/// Returns the list of updated rows.
///
/// If [noReturn] is set to `true`, the updated rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> updateWhere(
_isd.DatabaseSession session, {
required _isd.ColumnValueListBuilder<UniqueCascadeChildUpdateTable>
columnValues,
required _isd.WhereExpressionBuilder<UniqueCascadeChildTable> where,
int? limit,
int? offset,
_isd.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_isd.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_isd.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.updateWhere<UniqueCascadeChild>(
columnValues: columnValues(UniqueCascadeChild.t.updateTable),
where: where(UniqueCascadeChild.t),
limit: limit,
offset: offset,
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Deletes all [UniqueCascadeChild]s in the list and returns the deleted rows.
///
/// To specify the order of the returned rows use [orderBy] or [orderByList]
/// when sorting by multiple columns.
///
/// This is an atomic operation, meaning that if one of the rows fail to
/// be deleted, none of the rows will be deleted.
///
/// If [noReturn] is set to `true`, the deleted rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> delete(
_isd.DatabaseSession session,
List<UniqueCascadeChild> rows, {
_isd.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_isd.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_isd.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.delete<UniqueCascadeChild>(
rows,
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Deletes a single [UniqueCascadeChild].
Future<UniqueCascadeChild> deleteRow(
_isd.DatabaseSession session,
UniqueCascadeChild row, {
_isd.Transaction? transaction,
}) async {
return session.db.deleteRow<UniqueCascadeChild>(
row,
transaction: transaction,
);
}
/// Deletes all rows matching the [where] expression.
///
/// To specify the order of the returned rows use [orderBy] or [orderByList]
/// when sorting by multiple columns.
///
/// If [noReturn] is set to `true`, the deleted rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> deleteWhere(
_isd.DatabaseSession session, {
required _isd.WhereExpressionBuilder<UniqueCascadeChildTable> where,
_isd.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_isd.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_isd.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.deleteWhere<UniqueCascadeChild>(
where: where(UniqueCascadeChild.t),
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Counts the number of rows matching the [where] expression. If omitted,
/// will return the count of all rows in the table.
Future<int> count(
_isd.DatabaseSession session, {
_isd.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
int? limit,
_isd.Transaction? transaction,
}) async {
return session.db.count<UniqueCascadeChild>(
where: where?.call(UniqueCascadeChild.t),
limit: limit,
transaction: transaction,
);
}
/// Acquires row-level locks on [UniqueCascadeChild] rows matching the [where] expression.
Future<void> lockRows(
_isd.DatabaseSession session, {
required _isd.WhereExpressionBuilder<UniqueCascadeChildTable> where,
required _isd.LockMode lockMode,
required _isd.Transaction transaction,
_isd.LockBehavior lockBehavior = _isd.LockBehavior.wait,
}) async {
return session.db.lockRows<UniqueCascadeChild>(
where: where(UniqueCascadeChild.t),
lockMode: lockMode,
lockBehavior: lockBehavior,
transaction: transaction,
);
}
}
class UniqueCascadeChildAttachRowRepository {
const UniqueCascadeChildAttachRowRepository._();
/// Creates a relation between the given [UniqueCascadeChild] and [Person]
/// by setting the [UniqueCascadeChild]'s foreign key `parentId` to refer to the [Person].
Future<void> parent(
_isd.DatabaseSession session,
UniqueCascadeChild uniqueCascadeChild,
_iensfz4m.Person parent, {
_isd.Transaction? transaction,
}) async {
if (uniqueCascadeChild.id == null) {
throw ArgumentError.notNull('uniqueCascadeChild.id');
}
if (parent.id == null) {
throw ArgumentError.notNull('parent.id');
}
var $uniqueCascadeChild = uniqueCascadeChild.copyWith(parentId: parent.id);
await session.db.updateRow<UniqueCascadeChild>(
$uniqueCascadeChild,
columns: [UniqueCascadeChild.t.parentId],
transaction: transaction,
);
}
}
class UniqueCascadeChildDetachRowRepository {
const UniqueCascadeChildDetachRowRepository._();
/// Detaches the relation between this [UniqueCascadeChild] and the [Person] set in `parent`
/// by setting the [UniqueCascadeChild]'s foreign key `parentId` to `null`.
///
/// This removes the association between the two models without deleting
/// the related record.
Future<void> parent(
_isd.DatabaseSession session,
UniqueCascadeChild uniqueCascadeChild, {
_isd.Transaction? transaction,
}) async {
if (uniqueCascadeChild.id == null) {
throw ArgumentError.notNull('uniqueCascadeChild.id');
}
var $uniqueCascadeChild = uniqueCascadeChild.copyWith(parentId: null);
await session.db.updateRow<UniqueCascadeChild>(
$uniqueCascadeChild,
columns: [UniqueCascadeChild.t.parentId],
transaction: transaction,
);
}
}

View file

@ -0,0 +1,8 @@
# Ephemeral SQLite databases created by `serverpod_test`.
#
# `serverpod_test` derives one database file per test group from the configured
# `database.filePath` (see config/test.yaml), and the SQLite adapter does not
# create missing parent directories. So this directory has to exist in a fresh
# checkout, which is why it is committed while its contents are ignored.
*
!.gitignore

View file

@ -20,8 +20,14 @@ webServer:
publicScheme: http
# This is the database setup for your test server.
#
# The path stays inside `.test_databases/` because `serverpod_test` derives
# each ephemeral per-group database from it, keeping the directory:
# `.test_databases/test.db` -> `.test_databases/sp_test_<pid>_<token>.db`.
# With a bare filename those files land in the package root, where they are
# not covered by any ignore rule and litter the working copy.
database:
filePath: test.db
filePath: .test_databases/test.db
sessionLogs:
persistentEnabled: false

View file

@ -1,2 +1,22 @@
tags:
integration: {}
dst:
# A simulation drives many real SQLite transactions across replicas.
timeout: 5x
skip: 'Simulation suite: run with `dart test -P dst`'
# The simulation suite is excluded from an ordinary run. It is slow, and its
# seed base defaults to the current time, so it searches fresh schedules on
# every run and can fail for a defect unrelated to the change that triggered
# it. That is what makes it worth having, and what makes it a poor edit-loop
# signal.
#
# dart test -P dst the simulation suite
# DST_SEEDS=200 dart test -P dst a soak
# DST_SEED_BASE=<seed> DST_SEEDS=1 dart test -P dst replay one failure
presets:
dst:
include_tags: dst
tags:
dst:
skip: false

View file

@ -37,6 +37,7 @@ import 'town.dart' as _iytblq2r;
import 'types.dart' as _iwxwszsz;
import 'types_enum.dart' as _ire5m5mj;
import 'unique.dart' as _ivpwn84u;
import 'unique_cascade_child.dart' as _ixnh46zn;
import 'unique_composite.dart' as _iv4klbbv;
import 'unique_discriminator.dart' as _ixfoa5hm;
import 'unique_no_release.dart' as _i91ey4jd;
@ -62,6 +63,7 @@ export 'town.dart';
export 'types.dart';
export 'types_enum.dart';
export 'unique.dart';
export 'unique_cascade_child.dart';
export 'unique_composite.dart';
export 'unique_discriminator.dart';
export 'unique_no_release.dart';
@ -1266,6 +1268,82 @@ class Protocol extends _is.DatabaseSerializationManager {
],
managed: true,
),
_isp.TableDefinition(
name: 'unique_cascade_child',
dartName: 'UniqueCascadeChild',
schema: 'public',
module: 'serverpod_offline_sync_test',
columns: [
_isp.ColumnDefinition(
name: 'id',
columnType: _isp.ColumnType.uuid,
isNullable: false,
dartType: 'UuidValue?',
columnDefault: 'random_v7',
),
_isp.ColumnDefinition(
name: 'scopeId',
columnType: _isp.ColumnType.bigint,
isNullable: true,
dartType: 'int?',
),
_isp.ColumnDefinition(
name: 'name',
columnType: _isp.ColumnType.text,
isNullable: false,
dartType: 'String',
),
_isp.ColumnDefinition(
name: 'parentId',
columnType: _isp.ColumnType.uuid,
isNullable: true,
dartType: 'UuidValue?',
),
],
foreignKeys: [
_isp.ForeignKeyDefinition(
constraintName: 'unique_cascade_child_fk_0',
columns: ['scopeId'],
referenceTable: 'crdt_scopes',
referenceTableSchema: 'public',
referenceColumns: ['id'],
onUpdate: _isp.ForeignKeyAction.noAction,
onDelete: _isp.ForeignKeyAction.cascade,
matchType: null,
),
_isp.ForeignKeyDefinition(
constraintName: 'unique_cascade_child_fk_1',
columns: ['parentId'],
referenceTable: 'person',
referenceTableSchema: 'public',
referenceColumns: ['id'],
onUpdate: _isp.ForeignKeyAction.noAction,
onDelete: _isp.ForeignKeyAction.cascade,
matchType: null,
deferrable: _isp.DeferrableConstraint.initiallyDeferred,
),
],
indexes: [
_isp.IndexDefinition(
indexName: 'unique_cascade_child__scopeId__name__unique_idx',
tableSpace: null,
elements: [
_isp.IndexElementDefinition(
type: _isp.IndexElementDefinitionType.column,
definition: 'scopeId',
),
_isp.IndexElementDefinition(
type: _isp.IndexElementDefinitionType.column,
definition: 'name',
),
],
type: 'btree',
isUnique: true,
isPrimary: false,
),
],
managed: true,
),
_isp.TableDefinition(
name: 'unique_composite',
dartName: 'UniqueComposite',
@ -1687,6 +1765,9 @@ class Protocol extends _is.DatabaseSerializationManager {
if (t == _ivpwn84u.Unique) {
return _ivpwn84u.Unique.fromJson(data) as T;
}
if (t == _ixnh46zn.UniqueCascadeChild) {
return _ixnh46zn.UniqueCascadeChild.fromJson(data) as T;
}
if (t == _iv4klbbv.UniqueComposite) {
return _iv4klbbv.UniqueComposite.fromJson(data) as T;
}
@ -1790,6 +1871,10 @@ class Protocol extends _is.DatabaseSerializationManager {
if (t == _is.getType<_ivpwn84u.Unique?>()) {
return (data != null ? _ivpwn84u.Unique.fromJson(data) : null) as T;
}
if (t == _is.getType<_ixnh46zn.UniqueCascadeChild?>()) {
return (data != null ? _ixnh46zn.UniqueCascadeChild.fromJson(data) : null)
as T;
}
if (t == _is.getType<_iv4klbbv.UniqueComposite?>()) {
return (data != null ? _iv4klbbv.UniqueComposite.fromJson(data) : null)
as T;
@ -1879,6 +1964,7 @@ class Protocol extends _is.DatabaseSerializationManager {
_iwxwszsz.Types => 'Types',
_ire5m5mj.TypesEnum => 'TypesEnum',
_ivpwn84u.Unique => 'Unique',
_ixnh46zn.UniqueCascadeChild => 'UniqueCascadeChild',
_iv4klbbv.UniqueComposite => 'UniqueComposite',
_ixfoa5hm.UniqueDiscriminator => 'UniqueDiscriminator',
_i91ey4jd.UniqueNoRelease => 'UniqueNoRelease',
@ -1941,6 +2027,8 @@ class Protocol extends _is.DatabaseSerializationManager {
return 'TypesEnum';
case _ivpwn84u.Unique():
return 'Unique';
case _ixnh46zn.UniqueCascadeChild():
return 'UniqueCascadeChild';
case _iv4klbbv.UniqueComposite():
return 'UniqueComposite';
case _ixfoa5hm.UniqueDiscriminator():
@ -2037,6 +2125,9 @@ class Protocol extends _is.DatabaseSerializationManager {
if (dataClassName == 'Unique') {
return deserialize<_ivpwn84u.Unique>(data['data']);
}
if (dataClassName == 'UniqueCascadeChild') {
return deserialize<_ixnh46zn.UniqueCascadeChild>(data['data']);
}
if (dataClassName == 'UniqueComposite') {
return deserialize<_iv4klbbv.UniqueComposite>(data['data']);
}
@ -2134,6 +2225,8 @@ class Protocol extends _is.DatabaseSerializationManager {
return _iwxwszsz.Types.t;
case _ivpwn84u.Unique:
return _ivpwn84u.Unique.t;
case _ixnh46zn.UniqueCascadeChild:
return _ixnh46zn.UniqueCascadeChild.t;
case _iv4klbbv.UniqueComposite:
return _iv4klbbv.UniqueComposite.t;
case _ixfoa5hm.UniqueDiscriminator:

View file

@ -0,0 +1,746 @@
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
/* To generate run: "serverpod generate" */
// ignore_for_file: implementation_imports
// ignore_for_file: library_private_types_in_public_api
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: public_member_api_docs
// ignore_for_file: type_literal_in_constant_pattern
// ignore_for_file: use_super_parameters
// ignore_for_file: invalid_use_of_internal_member
// ignore_for_file: dead_code, no_leading_underscores_for_library_prefixes
// ignore_for_file: unnecessary_null_comparison
import 'package:serverpod/serverpod.dart' as _is;
import 'package:serverpod_offline_sync_test_server/src/generated/protocol.dart'
as _ixxccm81;
import 'person.dart' as _iensfz4m;
abstract class UniqueCascadeChild
implements _is.TableRow<_is.UuidValue?>, _is.ProtocolSerialization {
UniqueCascadeChild._({
this.id,
this.scopeId,
required this.name,
this.parentId,
this.parent,
});
factory UniqueCascadeChild({
_is.UuidValue? id,
int? scopeId,
required String name,
_is.UuidValue? parentId,
_iensfz4m.Person? parent,
}) = _UniqueCascadeChildImpl;
factory UniqueCascadeChild.fromJson(Map<String, dynamic> jsonSerialization) {
return UniqueCascadeChild(
id: jsonSerialization['id'] == null
? null
: _is.UuidValueJsonExtension.fromJson(jsonSerialization['id']),
scopeId: jsonSerialization['scopeId'] as int?,
name: jsonSerialization['name'] as String,
parentId: jsonSerialization['parentId'] == null
? null
: _is.UuidValueJsonExtension.fromJson(jsonSerialization['parentId']),
parent: jsonSerialization['parent'] == null
? null
: _ixxccm81.Protocol().deserialize<_iensfz4m.Person>(
jsonSerialization['parent'],
),
);
}
static final t = UniqueCascadeChildTable();
static const db = UniqueCascadeChildRepository._();
@override
_is.UuidValue? id;
/// The scope owning this row. Maintained by the sync engine.
int? scopeId;
String name;
_is.UuidValue? parentId;
_iensfz4m.Person? parent;
@override
_is.Table<_is.UuidValue?> get table => t;
/// Returns a shallow copy of this [UniqueCascadeChild]
/// with some or all fields replaced by the given arguments.
@_is.useResult
UniqueCascadeChild copyWith({
_is.UuidValue? id,
int? scopeId,
String? name,
_is.UuidValue? parentId,
_iensfz4m.Person? parent,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'UniqueCascadeChild',
if (id != null) 'id': id?.toJson(),
if (scopeId != null) 'scopeId': scopeId,
'name': name,
if (parentId != null) 'parentId': parentId?.toJson(),
if (parent != null) 'parent': parent?.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'UniqueCascadeChild',
if (id != null) 'id': id?.toJson(),
if (scopeId != null) 'scopeId': scopeId,
'name': name,
if (parentId != null) 'parentId': parentId?.toJson(),
if (parent != null) 'parent': parent?.toJsonForProtocol(),
};
}
static UniqueCascadeChildInclude include({_iensfz4m.PersonInclude? parent}) {
return UniqueCascadeChildInclude._(parent: parent);
}
static UniqueCascadeChildIncludeList includeList({
_is.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
int? limit,
int? offset,
_is.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_is.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
UniqueCascadeChildInclude? include,
}) {
return UniqueCascadeChildIncludeList._(
where: where,
limit: limit,
offset: offset,
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
include: include,
);
}
@override
String toString() {
return _is.SerializationManager.encode(this);
}
}
class _Undefined {}
class _UniqueCascadeChildImpl extends UniqueCascadeChild {
_UniqueCascadeChildImpl({
_is.UuidValue? id,
int? scopeId,
required String name,
_is.UuidValue? parentId,
_iensfz4m.Person? parent,
}) : super._(
id: id,
scopeId: scopeId,
name: name,
parentId: parentId,
parent: parent,
);
/// Returns a shallow copy of this [UniqueCascadeChild]
/// with some or all fields replaced by the given arguments.
@_is.useResult
@override
UniqueCascadeChild copyWith({
Object? id = _Undefined,
Object? scopeId = _Undefined,
String? name,
Object? parentId = _Undefined,
Object? parent = _Undefined,
}) {
return UniqueCascadeChild(
id: id is _is.UuidValue? ? id : this.id,
scopeId: scopeId is int? ? scopeId : this.scopeId,
name: name ?? this.name,
parentId: parentId is _is.UuidValue? ? parentId : this.parentId,
parent: parent is _iensfz4m.Person? ? parent : this.parent?.copyWith(),
);
}
}
class UniqueCascadeChildUpdateTable
extends _is.UpdateTable<UniqueCascadeChildTable> {
UniqueCascadeChildUpdateTable(super.table);
_is.ColumnValue<int, int> scopeId(int? value) => _is.ColumnValue(
table.scopeId,
value,
);
_is.ColumnValue<String, String> name(String value) => _is.ColumnValue(
table.name,
value,
);
_is.ColumnValue<_is.UuidValue, _is.UuidValue> parentId(
_is.UuidValue? value,
) => _is.ColumnValue(
table.parentId,
value,
);
}
class UniqueCascadeChildTable extends _is.Table<_is.UuidValue?> {
UniqueCascadeChildTable({super.tableRelation})
: super(tableName: 'unique_cascade_child') {
updateTable = UniqueCascadeChildUpdateTable(this);
scopeId = _is.ColumnInt(
'scopeId',
this,
);
name = _is.ColumnString(
'name',
this,
);
parentId = _is.ColumnUuid(
'parentId',
this,
);
}
late final UniqueCascadeChildUpdateTable updateTable;
/// The scope owning this row. Maintained by the sync engine.
late final _is.ColumnInt scopeId;
late final _is.ColumnString name;
late final _is.ColumnUuid parentId;
_iensfz4m.PersonTable? _parent;
_iensfz4m.PersonTable get parent {
if (_parent != null) return _parent!;
_parent = _is.createRelationTable(
relationFieldName: 'parent',
field: UniqueCascadeChild.t.parentId,
foreignField: _iensfz4m.Person.t.id,
tableRelation: tableRelation,
createTable: (foreignTableRelation) =>
_iensfz4m.PersonTable(tableRelation: foreignTableRelation),
);
return _parent!;
}
@override
List<_is.Column> get columns => [
id,
scopeId,
name,
parentId,
];
@override
_is.Table? getRelationTable(String relationField) {
if (relationField == 'parent') {
return parent;
}
return null;
}
}
class UniqueCascadeChildInclude extends _is.IncludeObject {
UniqueCascadeChildInclude._({_iensfz4m.PersonInclude? parent}) {
_parent = parent;
}
_iensfz4m.PersonInclude? _parent;
@override
Map<String, _is.Include?> get includes => {'parent': _parent};
@override
_is.Table<_is.UuidValue?> get table => UniqueCascadeChild.t;
}
class UniqueCascadeChildIncludeList extends _is.IncludeList {
UniqueCascadeChildIncludeList._({
_is.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
super.limit,
super.offset,
super.orderBy,
super.orderByList,
super.include,
}) {
super.where = where?.call(UniqueCascadeChild.t);
}
@override
Map<String, _is.Include?> get includes => include?.includes ?? {};
@override
_is.Table<_is.UuidValue?> get table => UniqueCascadeChild.t;
}
class UniqueCascadeChildRepository {
const UniqueCascadeChildRepository._();
final attachRow = const UniqueCascadeChildAttachRowRepository._();
final detachRow = const UniqueCascadeChildDetachRowRepository._();
/// Returns a list of [UniqueCascadeChild]s matching the given query parameters.
///
/// Use [where] to specify which items to include in the return value.
/// If none is specified, all items will be returned.
///
/// To specify the order of the items use [orderBy] or [orderByList]
/// when sorting by multiple columns.
///
/// The maximum number of items can be set by [limit]. If no limit is set,
/// all items matching the query will be returned.
///
/// [offset] defines how many items to skip, after which [limit] (or all)
/// items are read from the database.
///
/// ```dart
/// var persons = await Persons.db.find(
/// session,
/// where: (t) => t.lastName.equals('Jones'),
/// orderBy: (t) => t.firstName,
/// limit: 100,
/// );
/// ```
Future<List<UniqueCascadeChild>> find(
_is.DatabaseSession session, {
_is.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
int? limit,
int? offset,
_is.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_is.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_is.Transaction? transaction,
UniqueCascadeChildInclude? include,
_is.LockMode? lockMode,
_is.LockBehavior? lockBehavior,
}) async {
return session.db.find<UniqueCascadeChild>(
where: where?.call(UniqueCascadeChild.t),
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
limit: limit,
offset: offset,
transaction: transaction,
include: include,
lockMode: lockMode,
lockBehavior: lockBehavior,
);
}
/// Returns the first matching [UniqueCascadeChild] matching the given query parameters.
///
/// Use [where] to specify which items to include in the return value.
/// If none is specified, all items will be returned.
///
/// To specify the order use [orderBy] or [orderByList]
/// when sorting by multiple columns.
///
/// [offset] defines how many items to skip, after which the next one will be picked.
///
/// ```dart
/// var youngestPerson = await Persons.db.findFirstRow(
/// session,
/// where: (t) => t.lastName.equals('Jones'),
/// orderBy: (t) => t.age,
/// );
/// ```
Future<UniqueCascadeChild?> findFirstRow(
_is.DatabaseSession session, {
_is.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
int? offset,
_is.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_is.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_is.Transaction? transaction,
UniqueCascadeChildInclude? include,
_is.LockMode? lockMode,
_is.LockBehavior? lockBehavior,
}) async {
return session.db.findFirstRow<UniqueCascadeChild>(
where: where?.call(UniqueCascadeChild.t),
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
offset: offset,
transaction: transaction,
include: include,
lockMode: lockMode,
lockBehavior: lockBehavior,
);
}
/// Finds a single [UniqueCascadeChild] by its [id] or null if no such row exists.
Future<UniqueCascadeChild?> findById(
_is.DatabaseSession session,
_is.UuidValue id, {
_is.Transaction? transaction,
UniqueCascadeChildInclude? include,
_is.LockMode? lockMode,
_is.LockBehavior? lockBehavior,
}) async {
return session.db.findById<UniqueCascadeChild>(
id,
transaction: transaction,
include: include,
lockMode: lockMode,
lockBehavior: lockBehavior,
);
}
/// Inserts all [UniqueCascadeChild]s in the list and returns the inserted rows.
///
/// The returned [UniqueCascadeChild]s will have their `id` fields set.
///
/// This is an atomic operation, meaning that if one of the rows fails to
/// insert, none of the rows will be inserted.
///
/// If [ignoreConflicts] is set to `true`, rows that conflict with existing
/// rows are silently skipped, and only the successfully inserted rows are
/// returned.
///
/// If [noReturn] is set to `true`, the inserted rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> insert(
_is.DatabaseSession session,
List<UniqueCascadeChild> rows, {
_is.Transaction? transaction,
bool ignoreConflicts = false,
bool noReturn = false,
}) async {
return session.db.insert<UniqueCascadeChild>(
rows,
transaction: transaction,
ignoreConflicts: ignoreConflicts,
noReturn: noReturn,
);
}
/// Inserts a single [UniqueCascadeChild] and returns the inserted row.
///
/// The returned [UniqueCascadeChild] will have its `id` field set.
Future<UniqueCascadeChild> insertRow(
_is.DatabaseSession session,
UniqueCascadeChild row, {
_is.Transaction? transaction,
}) async {
return session.db.insertRow<UniqueCascadeChild>(
row,
transaction: transaction,
);
}
/// Upserts all [UniqueCascadeChild]s in the list and returns the resulting rows.
///
/// If a row conflicts on the given [conflictColumns], the existing row is
/// updated with the new values. Otherwise, a new row is inserted.
///
/// If [updateColumns] is provided, only those columns will be updated on
/// conflict. If null, all non-conflict, non-id columns are updated.
///
/// If [updateWhere] is provided, the update only applies to rows matching the
/// given expression. Conflicting rows that don't match are skipped and not
/// returned, so the resulting list may be shorter than [rows].
///
/// The returned [UniqueCascadeChild]s will have their `id` fields set.
///
/// This is an atomic operation, meaning that if one of the rows fails,
/// none of the rows will be affected.
///
/// If [noReturn] is set to `true`, the resulting rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> upsert(
_is.DatabaseSession session,
List<UniqueCascadeChild> rows, {
required _is.ColumnSelections<UniqueCascadeChildTable> conflictColumns,
_is.ColumnSelections<UniqueCascadeChildTable>? updateColumns,
_is.WhereExpressionBuilder<UniqueCascadeChildTable>? updateWhere,
_is.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.upsert<UniqueCascadeChild>(
rows,
conflictColumns: conflictColumns(UniqueCascadeChild.t),
updateColumns: updateColumns?.call(UniqueCascadeChild.t),
updateWhere: updateWhere?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Upserts a single [UniqueCascadeChild] and returns the resulting row.
///
/// If the row conflicts on the given [conflictColumns], the existing row is
/// updated. Otherwise, a new row is inserted.
///
/// If [updateColumns] is provided, only those columns will be updated on
/// conflict. If null, all non-conflict, non-id columns are updated.
///
/// If [updateWhere] is provided, the update only applies when the existing
/// row matches the expression. Returns `null` if no row was affected — for
/// example when [updateWhere] does not match the conflicting row.
///
/// The returned [UniqueCascadeChild] will have its `id` field set.
Future<UniqueCascadeChild?> upsertRow(
_is.DatabaseSession session,
UniqueCascadeChild row, {
required _is.ColumnSelections<UniqueCascadeChildTable> conflictColumns,
_is.ColumnSelections<UniqueCascadeChildTable>? updateColumns,
_is.WhereExpressionBuilder<UniqueCascadeChildTable>? updateWhere,
_is.Transaction? transaction,
}) async {
return session.db.upsertRow<UniqueCascadeChild>(
row,
conflictColumns: conflictColumns(UniqueCascadeChild.t),
updateColumns: updateColumns?.call(UniqueCascadeChild.t),
updateWhere: updateWhere?.call(UniqueCascadeChild.t),
transaction: transaction,
);
}
/// Updates all [UniqueCascadeChild]s in the list and returns the updated rows. If
/// [columns] is provided, only those columns will be updated. Defaults to
/// all columns.
/// This is an atomic operation, meaning that if one of the rows fails to
/// update, none of the rows will be updated.
///
/// If [noReturn] is set to `true`, the updated rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> update(
_is.DatabaseSession session,
List<UniqueCascadeChild> rows, {
_is.ColumnSelections<UniqueCascadeChildTable>? columns,
_is.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.update<UniqueCascadeChild>(
rows,
columns: columns?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Updates a single [UniqueCascadeChild]. The row needs to have its id set.
/// Optionally, a list of [columns] can be provided to only update those
/// columns. Defaults to all columns.
Future<UniqueCascadeChild> updateRow(
_is.DatabaseSession session,
UniqueCascadeChild row, {
_is.ColumnSelections<UniqueCascadeChildTable>? columns,
_is.Transaction? transaction,
}) async {
return session.db.updateRow<UniqueCascadeChild>(
row,
columns: columns?.call(UniqueCascadeChild.t),
transaction: transaction,
);
}
/// Updates a single [UniqueCascadeChild] by its [id] with the specified [columnValues].
/// Returns the updated row or null if no row with the given id exists.
Future<UniqueCascadeChild?> updateById(
_is.DatabaseSession session,
_is.UuidValue id, {
required _is.ColumnValueListBuilder<UniqueCascadeChildUpdateTable>
columnValues,
_is.Transaction? transaction,
}) async {
return session.db.updateById<UniqueCascadeChild>(
id,
columnValues: columnValues(UniqueCascadeChild.t.updateTable),
transaction: transaction,
);
}
/// Updates all [UniqueCascadeChild]s matching the [where] expression with the specified [columnValues].
/// Returns the list of updated rows.
///
/// If [noReturn] is set to `true`, the updated rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> updateWhere(
_is.DatabaseSession session, {
required _is.ColumnValueListBuilder<UniqueCascadeChildUpdateTable>
columnValues,
required _is.WhereExpressionBuilder<UniqueCascadeChildTable> where,
int? limit,
int? offset,
_is.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_is.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_is.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.updateWhere<UniqueCascadeChild>(
columnValues: columnValues(UniqueCascadeChild.t.updateTable),
where: where(UniqueCascadeChild.t),
limit: limit,
offset: offset,
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Deletes all [UniqueCascadeChild]s in the list and returns the deleted rows.
///
/// To specify the order of the returned rows use [orderBy] or [orderByList]
/// when sorting by multiple columns.
///
/// This is an atomic operation, meaning that if one of the rows fail to
/// be deleted, none of the rows will be deleted.
///
/// If [noReturn] is set to `true`, the deleted rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> delete(
_is.DatabaseSession session,
List<UniqueCascadeChild> rows, {
_is.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_is.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_is.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.delete<UniqueCascadeChild>(
rows,
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Deletes a single [UniqueCascadeChild].
Future<UniqueCascadeChild> deleteRow(
_is.DatabaseSession session,
UniqueCascadeChild row, {
_is.Transaction? transaction,
}) async {
return session.db.deleteRow<UniqueCascadeChild>(
row,
transaction: transaction,
);
}
/// Deletes all rows matching the [where] expression.
///
/// To specify the order of the returned rows use [orderBy] or [orderByList]
/// when sorting by multiple columns.
///
/// If [noReturn] is set to `true`, the deleted rows are not read back from
/// the database and an empty list is returned. This avoids the overhead of
/// transferring and deserializing the rows when the result is not needed.
Future<List<UniqueCascadeChild>> deleteWhere(
_is.DatabaseSession session, {
required _is.WhereExpressionBuilder<UniqueCascadeChildTable> where,
_is.OrderByBuilder<UniqueCascadeChildTable>? orderBy,
_is.OrderByListBuilder<UniqueCascadeChildTable>? orderByList,
_is.Transaction? transaction,
bool noReturn = false,
}) async {
return session.db.deleteWhere<UniqueCascadeChild>(
where: where(UniqueCascadeChild.t),
orderBy: orderBy?.call(UniqueCascadeChild.t),
orderByList: orderByList?.call(UniqueCascadeChild.t),
transaction: transaction,
noReturn: noReturn,
);
}
/// Counts the number of rows matching the [where] expression. If omitted,
/// will return the count of all rows in the table.
Future<int> count(
_is.DatabaseSession session, {
_is.WhereExpressionBuilder<UniqueCascadeChildTable>? where,
int? limit,
_is.Transaction? transaction,
}) async {
return session.db.count<UniqueCascadeChild>(
where: where?.call(UniqueCascadeChild.t),
limit: limit,
transaction: transaction,
);
}
/// Acquires row-level locks on [UniqueCascadeChild] rows matching the [where] expression.
Future<void> lockRows(
_is.DatabaseSession session, {
required _is.WhereExpressionBuilder<UniqueCascadeChildTable> where,
required _is.LockMode lockMode,
required _is.Transaction transaction,
_is.LockBehavior lockBehavior = _is.LockBehavior.wait,
}) async {
return session.db.lockRows<UniqueCascadeChild>(
where: where(UniqueCascadeChild.t),
lockMode: lockMode,
lockBehavior: lockBehavior,
transaction: transaction,
);
}
}
class UniqueCascadeChildAttachRowRepository {
const UniqueCascadeChildAttachRowRepository._();
/// Creates a relation between the given [UniqueCascadeChild] and [Person]
/// by setting the [UniqueCascadeChild]'s foreign key `parentId` to refer to the [Person].
Future<void> parent(
_is.DatabaseSession session,
UniqueCascadeChild uniqueCascadeChild,
_iensfz4m.Person parent, {
_is.Transaction? transaction,
}) async {
if (uniqueCascadeChild.id == null) {
throw ArgumentError.notNull('uniqueCascadeChild.id');
}
if (parent.id == null) {
throw ArgumentError.notNull('parent.id');
}
var $uniqueCascadeChild = uniqueCascadeChild.copyWith(parentId: parent.id);
await session.db.updateRow<UniqueCascadeChild>(
$uniqueCascadeChild,
columns: [UniqueCascadeChild.t.parentId],
transaction: transaction,
);
}
}
class UniqueCascadeChildDetachRowRepository {
const UniqueCascadeChildDetachRowRepository._();
/// Detaches the relation between this [UniqueCascadeChild] and the [Person] set in `parent`
/// by setting the [UniqueCascadeChild]'s foreign key `parentId` to `null`.
///
/// This removes the association between the two models without deleting
/// the related record.
Future<void> parent(
_is.DatabaseSession session,
UniqueCascadeChild uniqueCascadeChild, {
_is.Transaction? transaction,
}) async {
if (uniqueCascadeChild.id == null) {
throw ArgumentError.notNull('uniqueCascadeChild.id');
}
var $uniqueCascadeChild = uniqueCascadeChild.copyWith(parentId: null);
await session.db.updateRow<UniqueCascadeChild>(
$uniqueCascadeChild,
columns: [UniqueCascadeChild.t.parentId],
transaction: transaction,
);
}
}

View file

@ -0,0 +1,6 @@
class: UniqueCascadeChild
table: unique_cascade_child
database: sync
fields:
name: String, unique(per=scopeId)
parent: Person?, relation(fk, optional, onDelete=Cascade, deferred)

View file

@ -0,0 +1,106 @@
{
"__className__": "serverpod.DatabaseMigration",
"actions": [
{
"__className__": "serverpod.DatabaseMigrationAction",
"type": "createTable",
"createTable": {
"__className__": "serverpod.TableDefinition",
"name": "unique_cascade_child",
"dartName": "UniqueCascadeChild",
"module": "serverpod_offline_sync_test",
"schema": "public",
"columns": [
{
"__className__": "serverpod.ColumnDefinition",
"name": "id",
"fieldName": "id",
"columnType": 7,
"isNullable": false,
"columnDefault": "random_v7",
"dartType": "UuidValue?"
},
{
"__className__": "serverpod.ColumnDefinition",
"name": "scopeId",
"fieldName": "scopeId",
"columnType": 6,
"isNullable": true,
"dartType": "int?"
},
{
"__className__": "serverpod.ColumnDefinition",
"name": "name",
"fieldName": "name",
"columnType": 0,
"isNullable": false,
"dartType": "String"
},
{
"__className__": "serverpod.ColumnDefinition",
"name": "parentId",
"fieldName": "parentId",
"columnType": 7,
"isNullable": true,
"dartType": "UuidValue?"
}
],
"foreignKeys": [
{
"__className__": "serverpod.ForeignKeyDefinition",
"constraintName": "unique_cascade_child_fk_0",
"columns": [
"scopeId"
],
"referenceTable": "crdt_scopes",
"referenceTableSchema": "public",
"referenceColumns": [
"id"
],
"onUpdate": 3,
"onDelete": 4
},
{
"__className__": "serverpod.ForeignKeyDefinition",
"constraintName": "unique_cascade_child_fk_1",
"columns": [
"parentId"
],
"referenceTable": "person",
"referenceTableSchema": "public",
"referenceColumns": [
"id"
],
"onUpdate": 3,
"onDelete": 4,
"deferrable": "initiallyDeferred"
}
],
"indexes": [
{
"__className__": "serverpod.IndexDefinition",
"indexName": "unique_cascade_child__scopeId__name__unique_idx",
"elements": [
{
"__className__": "serverpod.IndexElementDefinition",
"type": 0,
"definition": "scopeId"
},
{
"__className__": "serverpod.IndexElementDefinition",
"type": 0,
"definition": "name"
}
],
"type": "btree",
"isUnique": true,
"isPrimary": false
}
],
"managed": true
}
}
],
"warnings": [],
"migrationApiVersion": 1
}

View file

@ -0,0 +1,179 @@
BEGIN;
--
-- ACTION CREATE TABLE
--
CREATE TABLE "unique_cascade_child" (
"id" BLOB PRIMARY KEY DEFAULT (unhex(printf('%012x', CAST(unixepoch('now', 'subsecond') * 1000 AS INTEGER)) || '7' || substr(hex(randomblob(2)), 2, 3) || substr('89AB', 1 + (abs(random()) % 4), 1) || substr(hex(randomblob(8)), 2, 15))),
"scopeId" INTEGER,
"name" TEXT NOT NULL,
"parentId" BLOB,
CONSTRAINT "unique_cascade_child_fk_0" FOREIGN KEY ("scopeId") REFERENCES "crdt_scopes" ("id") ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT "unique_cascade_child_fk_1" FOREIGN KEY ("parentId") REFERENCES "person" ("id") ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED
) STRICT;
-- Indexes
CREATE UNIQUE INDEX "unique_cascade_child__scopeId__name__unique_idx" ON "unique_cascade_child" ("scopeId", "name");
--
-- STORE COLUMN TYPES FOR MIGRATIONS
--
DROP TABLE IF EXISTS "serverpod_sqlite_schema";
CREATE TABLE "serverpod_sqlite_schema" (
"table_name" TEXT NOT NULL,
"column_name" TEXT NOT NULL,
"column_type" TEXT NOT NULL,
"column_vector_dimension" INTEGER,
PRIMARY KEY ("table_name", "column_name")
);
INSERT INTO "serverpod_sqlite_schema" VALUES
('address', 'id', 'uuid', NULL),
('address', 'inhabitantId', 'uuid', NULL),
('city', 'id', 'uuid', NULL),
('company', 'id', 'uuid', NULL),
('company', 'townId', 'uuid', NULL),
('fk_chain_cascade_middle', 'id', 'uuid', NULL),
('fk_chain_cascade_middle', 'rootId', 'uuid', NULL),
('fk_chain_middle_cascade_child', 'id', 'uuid', NULL),
('fk_chain_middle_cascade_child', 'restrictBlockerId', 'uuid', NULL),
('fk_chain_middle_set_null_child', 'id', 'uuid', NULL),
('fk_chain_middle_set_null_child', 'restrictBlockerId', 'uuid', NULL),
('fk_chain_restrict_blocker', 'id', 'uuid', NULL),
('fk_chain_restrict_blocker', 'cascadeMiddleId', 'uuid', NULL),
('fk_chain_root', 'id', 'uuid', NULL),
('fk_chain_set_null_cascade_child', 'id', 'uuid', NULL),
('fk_chain_set_null_cascade_child', 'setNullMiddleId', 'uuid', NULL),
('fk_chain_set_null_middle', 'id', 'uuid', NULL),
('fk_chain_set_null_middle', 'cascadeMiddleId', 'uuid', NULL),
('fk_chain_set_null_restrict_child', 'id', 'uuid', NULL),
('fk_chain_set_null_restrict_child', 'setNullMiddleId', 'uuid', NULL),
('fk_chain_set_null_set_null_child', 'id', 'uuid', NULL),
('fk_chain_set_null_set_null_child', 'setNullMiddleId', 'uuid', NULL),
('organization', 'id', 'uuid', NULL),
('organization', 'cityId', 'uuid', NULL),
('person', 'id', 'uuid', NULL),
('person', 'organizationId', 'uuid', NULL),
('person', 'oldCompanyId', 'uuid', NULL),
('person', 'cityId', 'uuid', NULL),
('required_set_null_child', 'id', 'uuid', NULL),
('required_set_null_child', 'parentId', 'uuid', NULL),
('restrict_child', 'id', 'uuid', NULL),
('restrict_child', 'parentId', 'uuid', NULL),
('town', 'id', 'uuid', NULL),
('town', 'cityId', 'uuid', NULL),
('town', 'mayorId', 'uuid', NULL),
('types', 'id', 'uuid', NULL),
('types', 'aBool', 'boolean', NULL),
('types', 'aDateTime', 'timestampWithoutTimeZone', NULL),
('types', 'optionalUuid', 'uuid', NULL),
('unique', 'id', 'uuid', NULL),
('unique_cascade_child', 'id', 'uuid', NULL),
('unique_cascade_child', 'parentId', 'uuid', NULL),
('unique_composite', 'id', 'uuid', NULL),
('unique_discriminator', 'id', 'uuid', NULL),
('unique_no_release', 'id', 'uuid', NULL),
('unique_set_null_child', 'id', 'uuid', NULL),
('unique_set_null_child', 'parentId', 'uuid', NULL),
('unique_uuid', 'id', 'uuid', NULL),
('unique_uuid', 'value', 'uuid', NULL),
('serverpod_cloud_storage', 'addedTime', 'timestampWithoutTimeZone', NULL),
('serverpod_cloud_storage', 'expiration', 'timestampWithoutTimeZone', NULL),
('serverpod_cloud_storage', 'verified', 'boolean', NULL),
('serverpod_cloud_storage_direct_download', 'expiration', 'timestampWithoutTimeZone', NULL),
('serverpod_cloud_storage_direct_upload', 'expiration', 'timestampWithoutTimeZone', NULL),
('serverpod_cloud_storage_direct_upload', 'preventOverwrite', 'boolean', NULL),
('serverpod_future_call', 'time', 'timestampWithoutTimeZone', NULL),
('serverpod_future_call', 'scheduling', 'json', NULL),
('serverpod_future_call_claim', 'lastHeartbeatTime', 'timestampWithoutTimeZone', NULL),
('serverpod_health_connection_info', 'timestamp', 'timestampWithoutTimeZone', NULL),
('serverpod_health_metric', 'timestamp', 'timestampWithoutTimeZone', NULL),
('serverpod_health_metric', 'isHealthy', 'boolean', NULL),
('serverpod_log', 'time', 'timestampWithoutTimeZone', NULL),
('serverpod_message_log', 'slow', 'boolean', NULL),
('serverpod_migrations', 'timestamp', 'timestampWithoutTimeZone', NULL),
('serverpod_query_log', 'slow', 'boolean', NULL),
('serverpod_runtime_settings', 'logSettings', 'json', NULL),
('serverpod_runtime_settings', 'logSettingsOverrides', 'json', NULL),
('serverpod_runtime_settings', 'logServiceCalls', 'boolean', NULL),
('serverpod_runtime_settings', 'logMalformedCalls', 'boolean', NULL),
('serverpod_session_log', 'time', 'timestampWithoutTimeZone', NULL),
('serverpod_session_log', 'slow', 'boolean', NULL),
('serverpod_session_log', 'isOpen', 'boolean', NULL),
('serverpod_session_log', 'touched', 'timestampWithoutTimeZone', NULL),
('serverpod_auth_core_jwt_refresh_token', 'id', 'uuid', NULL),
('serverpod_auth_core_jwt_refresh_token', 'authUserId', 'uuid', NULL),
('serverpod_auth_core_jwt_refresh_token', 'scopeNames', 'json', NULL),
('serverpod_auth_core_jwt_refresh_token', 'lastUpdatedAt', 'timestampWithoutTimeZone', NULL),
('serverpod_auth_core_jwt_refresh_token', 'createdAt', 'timestampWithoutTimeZone', NULL),
('serverpod_auth_core_profile', 'id', 'uuid', NULL),
('serverpod_auth_core_profile', 'authUserId', 'uuid', NULL),
('serverpod_auth_core_profile', 'createdAt', 'timestampWithoutTimeZone', NULL),
('serverpod_auth_core_profile', 'imageId', 'uuid', NULL),
('serverpod_auth_core_profile_image', 'id', 'uuid', NULL),
('serverpod_auth_core_profile_image', 'userProfileId', 'uuid', NULL),
('serverpod_auth_core_profile_image', 'createdAt', 'timestampWithoutTimeZone', NULL),
('serverpod_auth_core_session', 'id', 'uuid', NULL),
('serverpod_auth_core_session', 'authUserId', 'uuid', NULL),
('serverpod_auth_core_session', 'scopeNames', 'json', NULL),
('serverpod_auth_core_session', 'createdAt', 'timestampWithoutTimeZone', NULL),
('serverpod_auth_core_session', 'lastUsedAt', 'timestampWithoutTimeZone', NULL),
('serverpod_auth_core_session', 'expiresAt', 'timestampWithoutTimeZone', NULL),
('serverpod_auth_core_user', 'id', 'uuid', NULL),
('serverpod_auth_core_user', 'createdAt', 'timestampWithoutTimeZone', NULL),
('serverpod_auth_core_user', 'scopeNames', 'json', NULL),
('serverpod_auth_core_user', 'blocked', 'boolean', NULL),
('crdt_data_fields', 'hlcDatetime', 'timestampWithoutTimeZone', NULL),
('crdt_data_foreign_key', 'attemptedValue', 'uuid', NULL),
('crdt_data_foreign_key', 'visibleValue', 'uuid', NULL),
('crdt_data_rows', 'hlcDatetime', 'timestampWithoutTimeZone', NULL),
('crdt_data_rows', 'uuidRowId', 'uuid', NULL),
('crdt_data_tombstone', 'hlcDatetime', 'timestampWithoutTimeZone', NULL),
('crdt_nodes', 'uuidNodeId', 'uuid', NULL),
('crdt_nodes', 'lastHlc', 'jsonb', NULL),
('crdt_scope_members', 'userUuid', 'uuid', NULL),
('crdt_scope_nodes', 'lastReceivedHlc', 'jsonb', NULL),
('crdt_scopes', 'uuidScopeId', 'uuid', NULL),
('crdt_sync_integrity_violations', 'uuidRowId', 'uuid', NULL),
('crdt_sync_integrity_violations', 'ownerScopeUuid', 'uuid', NULL),
('crdt_sync_integrity_violations', 'incomingScopeUuid', 'uuid', NULL),
('crdt_sync_integrity_violations', 'uuidNodeId', 'uuid', NULL),
('crdt_sync_integrity_violations', 'hlcDatetime', 'timestampWithoutTimeZone', NULL),
('crdt_sync_integrity_violations', 'firstSeenAt', 'timestampWithoutTimeZone', NULL),
('crdt_sync_integrity_violations', 'lastSeenAt', 'timestampWithoutTimeZone', NULL);
--
-- MIGRATION VERSION FOR serverpod_offline_sync_test
--
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
VALUES ('serverpod_offline_sync_test', '20260901174859443', (unixepoch('now', 'subsecond') * 1000))
ON CONFLICT ("module")
DO UPDATE SET "version" = '20260901174859443', "timestamp" = (unixepoch('now', 'subsecond') * 1000);
--
-- MIGRATION VERSION FOR serverpod
--
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
VALUES ('serverpod', '20260824182259319', (unixepoch('now', 'subsecond') * 1000))
ON CONFLICT ("module")
DO UPDATE SET "version" = '20260824182259319', "timestamp" = (unixepoch('now', 'subsecond') * 1000);
--
-- MIGRATION VERSION FOR serverpod_auth_core
--
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
VALUES ('serverpod_auth_core', '20260824182354731', (unixepoch('now', 'subsecond') * 1000))
ON CONFLICT ("module")
DO UPDATE SET "version" = '20260824182354731', "timestamp" = (unixepoch('now', 'subsecond') * 1000);
--
-- MIGRATION VERSION FOR serverpod_offline_sync
--
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
VALUES ('serverpod_offline_sync', '20260831202217145', (unixepoch('now', 'subsecond') * 1000))
ON CONFLICT ("module")
DO UPDATE SET "version" = '20260831202217145', "timestamp" = (unixepoch('now', 'subsecond') * 1000);
COMMIT;

View file

@ -7,3 +7,4 @@
20260703114649226
20260824213459360
20260831202219662
20260901174859443

View file

@ -16,6 +16,7 @@ dependencies:
path: ../../packages/serverpod_offline_sync_server
dev_dependencies:
clock: ^1.1.2
lints: '>=3.0.0 <7.0.0'
path: ^1.9.1
serverpod_database: 4.0.0-rc.1

Some files were not shown because too many files have changed in this diff Show more