feat: notes in studysets, synced and merged as cards are, with tags
Server: three synced tables, only additions (migration
20261002191122122-notes): `note` (its studyset, a fractional position),
`note_revision` (append-only, as a card's: parents, author, report,
the payload {schemaVersion, title, body}) and `note_tag` (one row per
assignment, never updated, as `card_tag`). Each indexes `spaceId`, and
everything goes with its space, studyset, note or tag. A migration of
synced tables locks app builds from before it out of syncing (ADR 0002,
rule 3): cheap now, before the first release.
App, `feature/note`:
- `NoteContent` is a title and rich text, merged apart (ADR 0003): a
title changed on one device and the body on another both survive, a
body changed on two is a conflict.
- `NoteRepository` creates a note at the end of its studyset, saves an
edit on the revisions it started from (`saveEdit`, as the card
composer now does), says when a note was last edited (its newest
head's UUID v7), counts notes per studyset, and deletes a note's
revisions blanked first (ADR 0002, rule 2).
- Notes share the person's tags: `setTagsOfNote`, and folding tags of
one name or undoing a tag's deletion covers notes too.
- The delayed deletion with its Undo moves to `core/async`
(`DelayedDeletions`): `StudysetDeletions` builds on it and now takes
a studyset's notes too; `NoteDeletions` deletes a single note.
Tests: content, merge, payload, repository, deletions, tags, the device
migration guard, and sync tests against the server (four).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
9639ce8569
commit
f3b56f2c0c
14 changed files with 25469 additions and 131 deletions
724
halkyon_learn_server/lib/src/generated/note/note.dart
Normal file
724
halkyon_learn_server/lib/src/generated/note/note.dart
Normal file
|
|
@ -0,0 +1,724 @@
|
|||
/* 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, unnecessary_null_comparison
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:halkyon_learn_server/src/generated/protocol.dart' as _i5lsenq5;
|
||||
import 'package:serverpod/serverpod.dart' as _is;
|
||||
import '../studyset/studyset.dart' as _ie5k1jc2;
|
||||
|
||||
/// A note in a studyset: rich text the person writes and reads, never studied.
|
||||
/// Its content lives in its revisions (NoteRevision), never in this row: content
|
||||
/// is append-only (ADR 0001, rule 2), as a card's is. Synced; its space owns it.
|
||||
abstract class Note
|
||||
implements _is.TableRow<_is.UuidValue?>, _is.ProtocolSerialization {
|
||||
Note._({
|
||||
this.id,
|
||||
this.spaceId,
|
||||
required this.studysetId,
|
||||
this.studyset,
|
||||
required this.position,
|
||||
});
|
||||
|
||||
factory Note({
|
||||
_is.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _is.UuidValue studysetId,
|
||||
_ie5k1jc2.Studyset? studyset,
|
||||
required String position,
|
||||
}) = _NoteImpl;
|
||||
|
||||
factory Note.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return Note(
|
||||
id: jsonSerialization['id'] == null
|
||||
? null
|
||||
: _is.UuidValueJsonExtension.fromJson(jsonSerialization['id']),
|
||||
spaceId: jsonSerialization['spaceId'] as int?,
|
||||
studysetId: _is.UuidValueJsonExtension.fromJson(
|
||||
jsonSerialization['studysetId'],
|
||||
),
|
||||
studyset: jsonSerialization['studyset'] == null
|
||||
? null
|
||||
: _i5lsenq5.Protocol().deserialize<_ie5k1jc2.Studyset>(
|
||||
jsonSerialization['studyset'],
|
||||
),
|
||||
position: jsonSerialization['position'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
static final t = NoteTable();
|
||||
|
||||
static const db = NoteRepository._();
|
||||
|
||||
@override
|
||||
_is.UuidValue? id;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
int? spaceId;
|
||||
|
||||
_is.UuidValue studysetId;
|
||||
|
||||
/// The studyset the note belongs to; the note goes with it.
|
||||
_ie5k1jc2.Studyset? studyset;
|
||||
|
||||
/// Where the note stands among its studyset's notes: a fractional index, as a
|
||||
/// card's position; last writer wins.
|
||||
String position;
|
||||
|
||||
@override
|
||||
_is.Table<_is.UuidValue?> get table => t;
|
||||
|
||||
/// Returns a shallow copy of this [Note]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_is.useResult
|
||||
Note copyWith({
|
||||
_is.UuidValue? id,
|
||||
int? spaceId,
|
||||
_is.UuidValue? studysetId,
|
||||
_ie5k1jc2.Studyset? studyset,
|
||||
String? position,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'Note',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'studysetId': studysetId.toJson(),
|
||||
if (studyset != null) 'studyset': studyset?.toJson(),
|
||||
'position': position,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'Note',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'studysetId': studysetId.toJson(),
|
||||
if (studyset != null) 'studyset': studyset?.toJsonForProtocol(),
|
||||
'position': position,
|
||||
};
|
||||
}
|
||||
|
||||
static NoteInclude include({_ie5k1jc2.StudysetInclude? studyset}) {
|
||||
return NoteInclude._(studyset: studyset);
|
||||
}
|
||||
|
||||
static NoteIncludeList includeList({
|
||||
_is.WhereExpressionBuilder<NoteTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTable>? orderByList,
|
||||
NoteInclude? include,
|
||||
}) {
|
||||
return NoteIncludeList._(
|
||||
where: where,
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(Note.t),
|
||||
orderByList: orderByList?.call(Note.t),
|
||||
include: include,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _is.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _NoteImpl extends Note {
|
||||
_NoteImpl({
|
||||
_is.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _is.UuidValue studysetId,
|
||||
_ie5k1jc2.Studyset? studyset,
|
||||
required String position,
|
||||
}) : super._(
|
||||
id: id,
|
||||
spaceId: spaceId,
|
||||
studysetId: studysetId,
|
||||
studyset: studyset,
|
||||
position: position,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [Note]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_is.useResult
|
||||
@override
|
||||
Note copyWith({
|
||||
Object? id = _Undefined,
|
||||
Object? spaceId = _Undefined,
|
||||
_is.UuidValue? studysetId,
|
||||
Object? studyset = _Undefined,
|
||||
String? position,
|
||||
}) {
|
||||
return Note(
|
||||
id: id is _is.UuidValue? ? id : this.id,
|
||||
spaceId: spaceId is int? ? spaceId : this.spaceId,
|
||||
studysetId: studysetId ?? this.studysetId,
|
||||
studyset: studyset is _ie5k1jc2.Studyset?
|
||||
? studyset
|
||||
: this.studyset?.copyWith(),
|
||||
position: position ?? this.position,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NoteUpdateTable extends _is.UpdateTable<NoteTable> {
|
||||
NoteUpdateTable(super.table);
|
||||
|
||||
_is.ColumnValue<int, int> spaceId(int? value) => _is.ColumnValue(
|
||||
table.spaceId,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<_is.UuidValue, _is.UuidValue> studysetId(
|
||||
_is.UuidValue value,
|
||||
) => _is.ColumnValue(
|
||||
table.studysetId,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<String, String> position(String value) => _is.ColumnValue(
|
||||
table.position,
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
class NoteTable extends _is.Table<_is.UuidValue?> {
|
||||
NoteTable({super.tableRelation}) : super(tableName: 'note') {
|
||||
updateTable = NoteUpdateTable(this);
|
||||
spaceId = _is.ColumnInt(
|
||||
'spaceId',
|
||||
this,
|
||||
);
|
||||
studysetId = _is.ColumnUuid(
|
||||
'studysetId',
|
||||
this,
|
||||
);
|
||||
position = _is.ColumnString(
|
||||
'position',
|
||||
this,
|
||||
);
|
||||
}
|
||||
|
||||
late final NoteUpdateTable updateTable;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
late final _is.ColumnInt spaceId;
|
||||
|
||||
late final _is.ColumnUuid studysetId;
|
||||
|
||||
/// The studyset the note belongs to; the note goes with it.
|
||||
_ie5k1jc2.StudysetTable? _studyset;
|
||||
|
||||
/// Where the note stands among its studyset's notes: a fractional index, as a
|
||||
/// card's position; last writer wins.
|
||||
late final _is.ColumnString position;
|
||||
|
||||
_ie5k1jc2.StudysetTable get studyset {
|
||||
if (_studyset != null) return _studyset!;
|
||||
_studyset = _is.createRelationTable(
|
||||
relationFieldName: 'studyset',
|
||||
field: Note.t.studysetId,
|
||||
foreignField: _ie5k1jc2.Studyset.t.id,
|
||||
tableRelation: tableRelation,
|
||||
createTable: (foreignTableRelation) =>
|
||||
_ie5k1jc2.StudysetTable(tableRelation: foreignTableRelation),
|
||||
);
|
||||
return _studyset!;
|
||||
}
|
||||
|
||||
@override
|
||||
List<_is.Column> get columns => [
|
||||
id,
|
||||
spaceId,
|
||||
studysetId,
|
||||
position,
|
||||
];
|
||||
|
||||
@override
|
||||
_is.Table? getRelationTable(String relationField) {
|
||||
if (relationField == 'studyset') {
|
||||
return studyset;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class NoteInclude extends _is.IncludeObject {
|
||||
NoteInclude._({_ie5k1jc2.StudysetInclude? studyset}) {
|
||||
_studyset = studyset;
|
||||
}
|
||||
|
||||
_ie5k1jc2.StudysetInclude? _studyset;
|
||||
|
||||
@override
|
||||
Map<String, _is.Include?> get includes => {'studyset': _studyset};
|
||||
|
||||
@override
|
||||
_is.Table<_is.UuidValue?> get table => Note.t;
|
||||
}
|
||||
|
||||
class NoteIncludeList extends _is.IncludeList {
|
||||
NoteIncludeList._({
|
||||
_is.WhereExpressionBuilder<NoteTable>? where,
|
||||
super.limit,
|
||||
super.offset,
|
||||
super.orderBy,
|
||||
super.orderByList,
|
||||
super.include,
|
||||
}) {
|
||||
super.where = where?.call(Note.t);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, _is.Include?> get includes => include?.includes ?? {};
|
||||
|
||||
@override
|
||||
_is.Table<_is.UuidValue?> get table => Note.t;
|
||||
}
|
||||
|
||||
class NoteRepository {
|
||||
const NoteRepository._();
|
||||
|
||||
final attachRow = const NoteAttachRowRepository._();
|
||||
|
||||
/// Returns a list of [Note]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<Note>> find(
|
||||
_is.DatabaseSession session, {
|
||||
_is.WhereExpressionBuilder<NoteTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
NoteInclude? include,
|
||||
_is.LockMode? lockMode,
|
||||
_is.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.find<Note>(
|
||||
where: where?.call(Note.t),
|
||||
orderBy: orderBy?.call(Note.t),
|
||||
orderByList: orderByList?.call(Note.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the first matching [Note] 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<Note?> findFirstRow(
|
||||
_is.DatabaseSession session, {
|
||||
_is.WhereExpressionBuilder<NoteTable>? where,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
NoteInclude? include,
|
||||
_is.LockMode? lockMode,
|
||||
_is.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findFirstRow<Note>(
|
||||
where: where?.call(Note.t),
|
||||
orderBy: orderBy?.call(Note.t),
|
||||
orderByList: orderByList?.call(Note.t),
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Finds a single [Note] by its [id] or null if no such row exists.
|
||||
Future<Note?> findById(
|
||||
_is.DatabaseSession session,
|
||||
_is.UuidValue id, {
|
||||
_is.Transaction? transaction,
|
||||
NoteInclude? include,
|
||||
_is.LockMode? lockMode,
|
||||
_is.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findById<Note>(
|
||||
id,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts all [Note]s in the list and returns the inserted rows.
|
||||
///
|
||||
/// The returned [Note]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<Note>> insert(
|
||||
_is.DatabaseSession session,
|
||||
List<Note> rows, {
|
||||
_is.Transaction? transaction,
|
||||
bool ignoreConflicts = false,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.insert<Note>(
|
||||
rows,
|
||||
transaction: transaction,
|
||||
ignoreConflicts: ignoreConflicts,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts a single [Note] and returns the inserted row.
|
||||
///
|
||||
/// The returned [Note] will have its `id` field set.
|
||||
Future<Note> insertRow(
|
||||
_is.DatabaseSession session,
|
||||
Note row, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.insertRow<Note>(
|
||||
row,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts all [Note]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 [Note]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<Note>> upsert(
|
||||
_is.DatabaseSession session,
|
||||
List<Note> rows, {
|
||||
required _is.ColumnSelections<NoteTable> conflictColumns,
|
||||
_is.ColumnSelections<NoteTable>? updateColumns,
|
||||
_is.WhereExpressionBuilder<NoteTable>? updateWhere,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.upsert<Note>(
|
||||
rows,
|
||||
conflictColumns: conflictColumns(Note.t),
|
||||
updateColumns: updateColumns?.call(Note.t),
|
||||
updateWhere: updateWhere?.call(Note.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts a single [Note] 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 [Note] will have its `id` field set.
|
||||
Future<Note?> upsertRow(
|
||||
_is.DatabaseSession session,
|
||||
Note row, {
|
||||
required _is.ColumnSelections<NoteTable> conflictColumns,
|
||||
_is.ColumnSelections<NoteTable>? updateColumns,
|
||||
_is.WhereExpressionBuilder<NoteTable>? updateWhere,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.upsertRow<Note>(
|
||||
row,
|
||||
conflictColumns: conflictColumns(Note.t),
|
||||
updateColumns: updateColumns?.call(Note.t),
|
||||
updateWhere: updateWhere?.call(Note.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [Note]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<Note>> update(
|
||||
_is.DatabaseSession session,
|
||||
List<Note> rows, {
|
||||
_is.ColumnSelections<NoteTable>? columns,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.update<Note>(
|
||||
rows,
|
||||
columns: columns?.call(Note.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [Note]. 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<Note> updateRow(
|
||||
_is.DatabaseSession session,
|
||||
Note row, {
|
||||
_is.ColumnSelections<NoteTable>? columns,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateRow<Note>(
|
||||
row,
|
||||
columns: columns?.call(Note.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [Note] by its [id] with the specified [columnValues].
|
||||
/// Returns the updated row or null if no row with the given id exists.
|
||||
Future<Note?> updateById(
|
||||
_is.DatabaseSession session,
|
||||
_is.UuidValue id, {
|
||||
required _is.ColumnValueListBuilder<NoteUpdateTable> columnValues,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateById<Note>(
|
||||
id,
|
||||
columnValues: columnValues(Note.t.updateTable),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [Note]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<Note>> updateWhere(
|
||||
_is.DatabaseSession session, {
|
||||
required _is.ColumnValueListBuilder<NoteUpdateTable> columnValues,
|
||||
required _is.WhereExpressionBuilder<NoteTable> where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.updateWhere<Note>(
|
||||
columnValues: columnValues(Note.t.updateTable),
|
||||
where: where(Note.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(Note.t),
|
||||
orderByList: orderByList?.call(Note.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes all [Note]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<Note>> delete(
|
||||
_is.DatabaseSession session,
|
||||
List<Note> rows, {
|
||||
_is.OrderByBuilder<NoteTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.delete<Note>(
|
||||
rows,
|
||||
orderBy: orderBy?.call(Note.t),
|
||||
orderByList: orderByList?.call(Note.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes a single [Note].
|
||||
Future<Note> deleteRow(
|
||||
_is.DatabaseSession session,
|
||||
Note row, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.deleteRow<Note>(
|
||||
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<Note>> deleteWhere(
|
||||
_is.DatabaseSession session, {
|
||||
required _is.WhereExpressionBuilder<NoteTable> where,
|
||||
_is.OrderByBuilder<NoteTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.deleteWhere<Note>(
|
||||
where: where(Note.t),
|
||||
orderBy: orderBy?.call(Note.t),
|
||||
orderByList: orderByList?.call(Note.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<NoteTable>? where,
|
||||
int? limit,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.count<Note>(
|
||||
where: where?.call(Note.t),
|
||||
limit: limit,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Acquires row-level locks on [Note] rows matching the [where] expression.
|
||||
Future<void> lockRows(
|
||||
_is.DatabaseSession session, {
|
||||
required _is.WhereExpressionBuilder<NoteTable> where,
|
||||
required _is.LockMode lockMode,
|
||||
required _is.Transaction transaction,
|
||||
_is.LockBehavior lockBehavior = _is.LockBehavior.wait,
|
||||
}) async {
|
||||
return session.db.lockRows<Note>(
|
||||
where: where(Note.t),
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NoteAttachRowRepository {
|
||||
const NoteAttachRowRepository._();
|
||||
|
||||
/// Creates a relation between the given [Note] and [Studyset]
|
||||
/// by setting the [Note]'s foreign key `studysetId` to refer to the [Studyset].
|
||||
Future<void> studyset(
|
||||
_is.DatabaseSession session,
|
||||
Note note,
|
||||
_ie5k1jc2.Studyset studyset, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
if (note.id == null) {
|
||||
throw ArgumentError.notNull('note.id');
|
||||
}
|
||||
if (studyset.id == null) {
|
||||
throw ArgumentError.notNull('studyset.id');
|
||||
}
|
||||
|
||||
var $note = note.copyWith(studysetId: studyset.id);
|
||||
await session.db.updateRow<Note>(
|
||||
$note,
|
||||
columns: [Note.t.studysetId],
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
869
halkyon_learn_server/lib/src/generated/note/note_revision.dart
Normal file
869
halkyon_learn_server/lib/src/generated/note/note_revision.dart
Normal file
|
|
@ -0,0 +1,869 @@
|
|||
/* 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, unnecessary_null_comparison
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:typed_data' as _idt;
|
||||
import 'package:halkyon_learn_server/src/generated/protocol.dart' as _i5lsenq5;
|
||||
import 'package:serverpod/serverpod.dart' as _is;
|
||||
import '../note/note.dart' as _iu6jc5sx;
|
||||
|
||||
/// One version of a note's content, never changed once written (ADR 0001,
|
||||
/// rule 2), merged as a card's revisions are (ADR 0003): editing appends a
|
||||
/// revision whose parents are the versions the edit started from, and a note's
|
||||
/// current versions are the revisions no other replaces. Deleting a note blanks
|
||||
/// every revision's payload first (ADR 0002, rule 2).
|
||||
abstract class NoteRevision
|
||||
implements _is.TableRow<_is.UuidValue?>, _is.ProtocolSerialization {
|
||||
NoteRevision._({
|
||||
this.id,
|
||||
this.spaceId,
|
||||
required this.noteId,
|
||||
this.note,
|
||||
required this.parents,
|
||||
required this.authorId,
|
||||
this.reportId,
|
||||
this.keyId,
|
||||
required this.payload,
|
||||
this.nonce,
|
||||
});
|
||||
|
||||
factory NoteRevision({
|
||||
_is.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _is.UuidValue noteId,
|
||||
_iu6jc5sx.Note? note,
|
||||
required List<_is.UuidValue> parents,
|
||||
required _is.UuidValue authorId,
|
||||
_is.UuidValue? reportId,
|
||||
String? keyId,
|
||||
required _idt.ByteData payload,
|
||||
_idt.ByteData? nonce,
|
||||
}) = _NoteRevisionImpl;
|
||||
|
||||
factory NoteRevision.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return NoteRevision(
|
||||
id: jsonSerialization['id'] == null
|
||||
? null
|
||||
: _is.UuidValueJsonExtension.fromJson(jsonSerialization['id']),
|
||||
spaceId: jsonSerialization['spaceId'] as int?,
|
||||
noteId: _is.UuidValueJsonExtension.fromJson(jsonSerialization['noteId']),
|
||||
note: jsonSerialization['note'] == null
|
||||
? null
|
||||
: _i5lsenq5.Protocol().deserialize<_iu6jc5sx.Note>(
|
||||
jsonSerialization['note'],
|
||||
),
|
||||
parents: _i5lsenq5.Protocol().deserialize<List<_is.UuidValue>>(
|
||||
jsonSerialization['parents'],
|
||||
),
|
||||
authorId: _is.UuidValueJsonExtension.fromJson(
|
||||
jsonSerialization['authorId'],
|
||||
),
|
||||
reportId: jsonSerialization['reportId'] == null
|
||||
? null
|
||||
: _is.UuidValueJsonExtension.fromJson(jsonSerialization['reportId']),
|
||||
keyId: jsonSerialization['keyId'] as String?,
|
||||
payload: _is.ByteDataJsonExtension.fromJson(jsonSerialization['payload']),
|
||||
nonce: jsonSerialization['nonce'] == null
|
||||
? null
|
||||
: _is.ByteDataJsonExtension.fromJson(jsonSerialization['nonce']),
|
||||
);
|
||||
}
|
||||
|
||||
static final t = NoteRevisionTable();
|
||||
|
||||
static const db = NoteRevisionRepository._();
|
||||
|
||||
@override
|
||||
_is.UuidValue? id;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
int? spaceId;
|
||||
|
||||
_is.UuidValue noteId;
|
||||
|
||||
/// The note this is a version of; its revisions go with it.
|
||||
_iu6jc5sx.Note? note;
|
||||
|
||||
/// The revisions this one replaces: none for a note's first, several when it
|
||||
/// resolves a conflict. Plain ids, since revisions can arrive in any order.
|
||||
List<_is.UuidValue> parents;
|
||||
|
||||
/// Who wrote it: the AuthUser's id (a synced table can't relate to the
|
||||
/// server-only AuthUser).
|
||||
_is.UuidValue authorId;
|
||||
|
||||
/// The report this revision answers, once reports exist; null otherwise.
|
||||
_is.UuidValue? reportId;
|
||||
|
||||
/// The encryption key's id; always null (ADR 0002, rule 6).
|
||||
String? keyId;
|
||||
|
||||
/// The content as UTF-8 JSON: {"schemaVersion", "title", "body"}.
|
||||
_idt.ByteData payload;
|
||||
|
||||
/// The encryption nonce; always null, like keyId.
|
||||
_idt.ByteData? nonce;
|
||||
|
||||
@override
|
||||
_is.Table<_is.UuidValue?> get table => t;
|
||||
|
||||
/// Returns a shallow copy of this [NoteRevision]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_is.useResult
|
||||
NoteRevision copyWith({
|
||||
_is.UuidValue? id,
|
||||
int? spaceId,
|
||||
_is.UuidValue? noteId,
|
||||
_iu6jc5sx.Note? note,
|
||||
List<_is.UuidValue>? parents,
|
||||
_is.UuidValue? authorId,
|
||||
_is.UuidValue? reportId,
|
||||
String? keyId,
|
||||
_idt.ByteData? payload,
|
||||
_idt.ByteData? nonce,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'NoteRevision',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'noteId': noteId.toJson(),
|
||||
if (note != null) 'note': note?.toJson(),
|
||||
'parents': parents.toJson(valueToJson: (v) => v.toJson()),
|
||||
'authorId': authorId.toJson(),
|
||||
if (reportId != null) 'reportId': reportId?.toJson(),
|
||||
if (keyId != null) 'keyId': keyId,
|
||||
'payload': payload.toJson(),
|
||||
if (nonce != null) 'nonce': nonce?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'NoteRevision',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'noteId': noteId.toJson(),
|
||||
if (note != null) 'note': note?.toJsonForProtocol(),
|
||||
'parents': parents.toJson(valueToJson: (v) => v.toJson()),
|
||||
'authorId': authorId.toJson(),
|
||||
if (reportId != null) 'reportId': reportId?.toJson(),
|
||||
if (keyId != null) 'keyId': keyId,
|
||||
'payload': payload.toJson(),
|
||||
if (nonce != null) 'nonce': nonce?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
static NoteRevisionInclude include({_iu6jc5sx.NoteInclude? note}) {
|
||||
return NoteRevisionInclude._(note: note);
|
||||
}
|
||||
|
||||
static NoteRevisionIncludeList includeList({
|
||||
_is.WhereExpressionBuilder<NoteRevisionTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteRevisionTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteRevisionTable>? orderByList,
|
||||
NoteRevisionInclude? include,
|
||||
}) {
|
||||
return NoteRevisionIncludeList._(
|
||||
where: where,
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(NoteRevision.t),
|
||||
orderByList: orderByList?.call(NoteRevision.t),
|
||||
include: include,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _is.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _NoteRevisionImpl extends NoteRevision {
|
||||
_NoteRevisionImpl({
|
||||
_is.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _is.UuidValue noteId,
|
||||
_iu6jc5sx.Note? note,
|
||||
required List<_is.UuidValue> parents,
|
||||
required _is.UuidValue authorId,
|
||||
_is.UuidValue? reportId,
|
||||
String? keyId,
|
||||
required _idt.ByteData payload,
|
||||
_idt.ByteData? nonce,
|
||||
}) : super._(
|
||||
id: id,
|
||||
spaceId: spaceId,
|
||||
noteId: noteId,
|
||||
note: note,
|
||||
parents: parents,
|
||||
authorId: authorId,
|
||||
reportId: reportId,
|
||||
keyId: keyId,
|
||||
payload: payload,
|
||||
nonce: nonce,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [NoteRevision]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_is.useResult
|
||||
@override
|
||||
NoteRevision copyWith({
|
||||
Object? id = _Undefined,
|
||||
Object? spaceId = _Undefined,
|
||||
_is.UuidValue? noteId,
|
||||
Object? note = _Undefined,
|
||||
List<_is.UuidValue>? parents,
|
||||
_is.UuidValue? authorId,
|
||||
Object? reportId = _Undefined,
|
||||
Object? keyId = _Undefined,
|
||||
_idt.ByteData? payload,
|
||||
Object? nonce = _Undefined,
|
||||
}) {
|
||||
return NoteRevision(
|
||||
id: id is _is.UuidValue? ? id : this.id,
|
||||
spaceId: spaceId is int? ? spaceId : this.spaceId,
|
||||
noteId: noteId ?? this.noteId,
|
||||
note: note is _iu6jc5sx.Note? ? note : this.note?.copyWith(),
|
||||
parents: parents ?? this.parents.map((e0) => e0).toList(),
|
||||
authorId: authorId ?? this.authorId,
|
||||
reportId: reportId is _is.UuidValue? ? reportId : this.reportId,
|
||||
keyId: keyId is String? ? keyId : this.keyId,
|
||||
payload: payload ?? this.payload.clone(),
|
||||
nonce: nonce is _idt.ByteData? ? nonce : this.nonce?.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NoteRevisionUpdateTable extends _is.UpdateTable<NoteRevisionTable> {
|
||||
NoteRevisionUpdateTable(super.table);
|
||||
|
||||
_is.ColumnValue<int, int> spaceId(int? value) => _is.ColumnValue(
|
||||
table.spaceId,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<_is.UuidValue, _is.UuidValue> noteId(_is.UuidValue value) =>
|
||||
_is.ColumnValue(
|
||||
table.noteId,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<List<_is.UuidValue>, List<_is.UuidValue>> parents(
|
||||
List<_is.UuidValue> value,
|
||||
) => _is.ColumnValue(
|
||||
table.parents,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<_is.UuidValue, _is.UuidValue> authorId(_is.UuidValue value) =>
|
||||
_is.ColumnValue(
|
||||
table.authorId,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<_is.UuidValue, _is.UuidValue> reportId(
|
||||
_is.UuidValue? value,
|
||||
) => _is.ColumnValue(
|
||||
table.reportId,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<String, String> keyId(String? value) => _is.ColumnValue(
|
||||
table.keyId,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<_idt.ByteData, _idt.ByteData> payload(_idt.ByteData value) =>
|
||||
_is.ColumnValue(
|
||||
table.payload,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<_idt.ByteData, _idt.ByteData> nonce(_idt.ByteData? value) =>
|
||||
_is.ColumnValue(
|
||||
table.nonce,
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
class NoteRevisionTable extends _is.Table<_is.UuidValue?> {
|
||||
NoteRevisionTable({super.tableRelation}) : super(tableName: 'note_revision') {
|
||||
updateTable = NoteRevisionUpdateTable(this);
|
||||
spaceId = _is.ColumnInt(
|
||||
'spaceId',
|
||||
this,
|
||||
);
|
||||
noteId = _is.ColumnUuid(
|
||||
'noteId',
|
||||
this,
|
||||
);
|
||||
parents = _is.ColumnSerializable<List<_is.UuidValue>>(
|
||||
'parents',
|
||||
this,
|
||||
);
|
||||
authorId = _is.ColumnUuid(
|
||||
'authorId',
|
||||
this,
|
||||
);
|
||||
reportId = _is.ColumnUuid(
|
||||
'reportId',
|
||||
this,
|
||||
);
|
||||
keyId = _is.ColumnString(
|
||||
'keyId',
|
||||
this,
|
||||
);
|
||||
payload = _is.ColumnByteData(
|
||||
'payload',
|
||||
this,
|
||||
);
|
||||
nonce = _is.ColumnByteData(
|
||||
'nonce',
|
||||
this,
|
||||
);
|
||||
}
|
||||
|
||||
late final NoteRevisionUpdateTable updateTable;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
late final _is.ColumnInt spaceId;
|
||||
|
||||
late final _is.ColumnUuid noteId;
|
||||
|
||||
/// The note this is a version of; its revisions go with it.
|
||||
_iu6jc5sx.NoteTable? _note;
|
||||
|
||||
/// The revisions this one replaces: none for a note's first, several when it
|
||||
/// resolves a conflict. Plain ids, since revisions can arrive in any order.
|
||||
late final _is.ColumnSerializable<List<_is.UuidValue>> parents;
|
||||
|
||||
/// Who wrote it: the AuthUser's id (a synced table can't relate to the
|
||||
/// server-only AuthUser).
|
||||
late final _is.ColumnUuid authorId;
|
||||
|
||||
/// The report this revision answers, once reports exist; null otherwise.
|
||||
late final _is.ColumnUuid reportId;
|
||||
|
||||
/// The encryption key's id; always null (ADR 0002, rule 6).
|
||||
late final _is.ColumnString keyId;
|
||||
|
||||
/// The content as UTF-8 JSON: {"schemaVersion", "title", "body"}.
|
||||
late final _is.ColumnByteData payload;
|
||||
|
||||
/// The encryption nonce; always null, like keyId.
|
||||
late final _is.ColumnByteData nonce;
|
||||
|
||||
_iu6jc5sx.NoteTable get note {
|
||||
if (_note != null) return _note!;
|
||||
_note = _is.createRelationTable(
|
||||
relationFieldName: 'note',
|
||||
field: NoteRevision.t.noteId,
|
||||
foreignField: _iu6jc5sx.Note.t.id,
|
||||
tableRelation: tableRelation,
|
||||
createTable: (foreignTableRelation) =>
|
||||
_iu6jc5sx.NoteTable(tableRelation: foreignTableRelation),
|
||||
);
|
||||
return _note!;
|
||||
}
|
||||
|
||||
@override
|
||||
List<_is.Column> get columns => [
|
||||
id,
|
||||
spaceId,
|
||||
noteId,
|
||||
parents,
|
||||
authorId,
|
||||
reportId,
|
||||
keyId,
|
||||
payload,
|
||||
nonce,
|
||||
];
|
||||
|
||||
@override
|
||||
_is.Table? getRelationTable(String relationField) {
|
||||
if (relationField == 'note') {
|
||||
return note;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class NoteRevisionInclude extends _is.IncludeObject {
|
||||
NoteRevisionInclude._({_iu6jc5sx.NoteInclude? note}) {
|
||||
_note = note;
|
||||
}
|
||||
|
||||
_iu6jc5sx.NoteInclude? _note;
|
||||
|
||||
@override
|
||||
Map<String, _is.Include?> get includes => {'note': _note};
|
||||
|
||||
@override
|
||||
_is.Table<_is.UuidValue?> get table => NoteRevision.t;
|
||||
}
|
||||
|
||||
class NoteRevisionIncludeList extends _is.IncludeList {
|
||||
NoteRevisionIncludeList._({
|
||||
_is.WhereExpressionBuilder<NoteRevisionTable>? where,
|
||||
super.limit,
|
||||
super.offset,
|
||||
super.orderBy,
|
||||
super.orderByList,
|
||||
super.include,
|
||||
}) {
|
||||
super.where = where?.call(NoteRevision.t);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, _is.Include?> get includes => include?.includes ?? {};
|
||||
|
||||
@override
|
||||
_is.Table<_is.UuidValue?> get table => NoteRevision.t;
|
||||
}
|
||||
|
||||
class NoteRevisionRepository {
|
||||
const NoteRevisionRepository._();
|
||||
|
||||
final attachRow = const NoteRevisionAttachRowRepository._();
|
||||
|
||||
/// Returns a list of [NoteRevision]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<NoteRevision>> find(
|
||||
_is.DatabaseSession session, {
|
||||
_is.WhereExpressionBuilder<NoteRevisionTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteRevisionTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteRevisionTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
NoteRevisionInclude? include,
|
||||
_is.LockMode? lockMode,
|
||||
_is.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.find<NoteRevision>(
|
||||
where: where?.call(NoteRevision.t),
|
||||
orderBy: orderBy?.call(NoteRevision.t),
|
||||
orderByList: orderByList?.call(NoteRevision.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the first matching [NoteRevision] 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<NoteRevision?> findFirstRow(
|
||||
_is.DatabaseSession session, {
|
||||
_is.WhereExpressionBuilder<NoteRevisionTable>? where,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteRevisionTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteRevisionTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
NoteRevisionInclude? include,
|
||||
_is.LockMode? lockMode,
|
||||
_is.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findFirstRow<NoteRevision>(
|
||||
where: where?.call(NoteRevision.t),
|
||||
orderBy: orderBy?.call(NoteRevision.t),
|
||||
orderByList: orderByList?.call(NoteRevision.t),
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Finds a single [NoteRevision] by its [id] or null if no such row exists.
|
||||
Future<NoteRevision?> findById(
|
||||
_is.DatabaseSession session,
|
||||
_is.UuidValue id, {
|
||||
_is.Transaction? transaction,
|
||||
NoteRevisionInclude? include,
|
||||
_is.LockMode? lockMode,
|
||||
_is.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findById<NoteRevision>(
|
||||
id,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts all [NoteRevision]s in the list and returns the inserted rows.
|
||||
///
|
||||
/// The returned [NoteRevision]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<NoteRevision>> insert(
|
||||
_is.DatabaseSession session,
|
||||
List<NoteRevision> rows, {
|
||||
_is.Transaction? transaction,
|
||||
bool ignoreConflicts = false,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.insert<NoteRevision>(
|
||||
rows,
|
||||
transaction: transaction,
|
||||
ignoreConflicts: ignoreConflicts,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts a single [NoteRevision] and returns the inserted row.
|
||||
///
|
||||
/// The returned [NoteRevision] will have its `id` field set.
|
||||
Future<NoteRevision> insertRow(
|
||||
_is.DatabaseSession session,
|
||||
NoteRevision row, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.insertRow<NoteRevision>(
|
||||
row,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts all [NoteRevision]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 [NoteRevision]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<NoteRevision>> upsert(
|
||||
_is.DatabaseSession session,
|
||||
List<NoteRevision> rows, {
|
||||
required _is.ColumnSelections<NoteRevisionTable> conflictColumns,
|
||||
_is.ColumnSelections<NoteRevisionTable>? updateColumns,
|
||||
_is.WhereExpressionBuilder<NoteRevisionTable>? updateWhere,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.upsert<NoteRevision>(
|
||||
rows,
|
||||
conflictColumns: conflictColumns(NoteRevision.t),
|
||||
updateColumns: updateColumns?.call(NoteRevision.t),
|
||||
updateWhere: updateWhere?.call(NoteRevision.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts a single [NoteRevision] 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 [NoteRevision] will have its `id` field set.
|
||||
Future<NoteRevision?> upsertRow(
|
||||
_is.DatabaseSession session,
|
||||
NoteRevision row, {
|
||||
required _is.ColumnSelections<NoteRevisionTable> conflictColumns,
|
||||
_is.ColumnSelections<NoteRevisionTable>? updateColumns,
|
||||
_is.WhereExpressionBuilder<NoteRevisionTable>? updateWhere,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.upsertRow<NoteRevision>(
|
||||
row,
|
||||
conflictColumns: conflictColumns(NoteRevision.t),
|
||||
updateColumns: updateColumns?.call(NoteRevision.t),
|
||||
updateWhere: updateWhere?.call(NoteRevision.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [NoteRevision]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<NoteRevision>> update(
|
||||
_is.DatabaseSession session,
|
||||
List<NoteRevision> rows, {
|
||||
_is.ColumnSelections<NoteRevisionTable>? columns,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.update<NoteRevision>(
|
||||
rows,
|
||||
columns: columns?.call(NoteRevision.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [NoteRevision]. 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<NoteRevision> updateRow(
|
||||
_is.DatabaseSession session,
|
||||
NoteRevision row, {
|
||||
_is.ColumnSelections<NoteRevisionTable>? columns,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateRow<NoteRevision>(
|
||||
row,
|
||||
columns: columns?.call(NoteRevision.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [NoteRevision] by its [id] with the specified [columnValues].
|
||||
/// Returns the updated row or null if no row with the given id exists.
|
||||
Future<NoteRevision?> updateById(
|
||||
_is.DatabaseSession session,
|
||||
_is.UuidValue id, {
|
||||
required _is.ColumnValueListBuilder<NoteRevisionUpdateTable> columnValues,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateById<NoteRevision>(
|
||||
id,
|
||||
columnValues: columnValues(NoteRevision.t.updateTable),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [NoteRevision]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<NoteRevision>> updateWhere(
|
||||
_is.DatabaseSession session, {
|
||||
required _is.ColumnValueListBuilder<NoteRevisionUpdateTable> columnValues,
|
||||
required _is.WhereExpressionBuilder<NoteRevisionTable> where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteRevisionTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteRevisionTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.updateWhere<NoteRevision>(
|
||||
columnValues: columnValues(NoteRevision.t.updateTable),
|
||||
where: where(NoteRevision.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(NoteRevision.t),
|
||||
orderByList: orderByList?.call(NoteRevision.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes all [NoteRevision]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<NoteRevision>> delete(
|
||||
_is.DatabaseSession session,
|
||||
List<NoteRevision> rows, {
|
||||
_is.OrderByBuilder<NoteRevisionTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteRevisionTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.delete<NoteRevision>(
|
||||
rows,
|
||||
orderBy: orderBy?.call(NoteRevision.t),
|
||||
orderByList: orderByList?.call(NoteRevision.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes a single [NoteRevision].
|
||||
Future<NoteRevision> deleteRow(
|
||||
_is.DatabaseSession session,
|
||||
NoteRevision row, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.deleteRow<NoteRevision>(
|
||||
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<NoteRevision>> deleteWhere(
|
||||
_is.DatabaseSession session, {
|
||||
required _is.WhereExpressionBuilder<NoteRevisionTable> where,
|
||||
_is.OrderByBuilder<NoteRevisionTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteRevisionTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.deleteWhere<NoteRevision>(
|
||||
where: where(NoteRevision.t),
|
||||
orderBy: orderBy?.call(NoteRevision.t),
|
||||
orderByList: orderByList?.call(NoteRevision.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<NoteRevisionTable>? where,
|
||||
int? limit,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.count<NoteRevision>(
|
||||
where: where?.call(NoteRevision.t),
|
||||
limit: limit,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Acquires row-level locks on [NoteRevision] rows matching the [where] expression.
|
||||
Future<void> lockRows(
|
||||
_is.DatabaseSession session, {
|
||||
required _is.WhereExpressionBuilder<NoteRevisionTable> where,
|
||||
required _is.LockMode lockMode,
|
||||
required _is.Transaction transaction,
|
||||
_is.LockBehavior lockBehavior = _is.LockBehavior.wait,
|
||||
}) async {
|
||||
return session.db.lockRows<NoteRevision>(
|
||||
where: where(NoteRevision.t),
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NoteRevisionAttachRowRepository {
|
||||
const NoteRevisionAttachRowRepository._();
|
||||
|
||||
/// Creates a relation between the given [NoteRevision] and [Note]
|
||||
/// by setting the [NoteRevision]'s foreign key `noteId` to refer to the [Note].
|
||||
Future<void> note(
|
||||
_is.DatabaseSession session,
|
||||
NoteRevision noteRevision,
|
||||
_iu6jc5sx.Note note, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
if (noteRevision.id == null) {
|
||||
throw ArgumentError.notNull('noteRevision.id');
|
||||
}
|
||||
if (note.id == null) {
|
||||
throw ArgumentError.notNull('note.id');
|
||||
}
|
||||
|
||||
var $noteRevision = noteRevision.copyWith(noteId: note.id);
|
||||
await session.db.updateRow<NoteRevision>(
|
||||
$noteRevision,
|
||||
columns: [NoteRevision.t.noteId],
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -32,10 +32,13 @@ import 'card/card.dart' as _ipiw1cmx;
|
|||
import 'card/card_revision.dart' as _ipbyuef1;
|
||||
import 'common/not_found_exception.dart' as _i8oee73b;
|
||||
import 'instance/instance_info.dart' as _iskrg2g3;
|
||||
import 'note/note.dart' as _i9njjhyv;
|
||||
import 'note/note_revision.dart' as _i6j5dng4;
|
||||
import 'review/review_log.dart' as _irzjbdqz;
|
||||
import 'settings/person_settings.dart' as _irnhx5e5;
|
||||
import 'studyset/studyset.dart' as _ikbclmae;
|
||||
import 'tag/card_tag.dart' as _i6jz6nyq;
|
||||
import 'tag/note_tag.dart' as _itkfn57x;
|
||||
import 'tag/tag.dart' as _ie8t3ar4;
|
||||
export 'asset/asset.dart';
|
||||
export 'asset/file_allowance.dart';
|
||||
|
|
@ -48,10 +51,13 @@ export 'card/card.dart';
|
|||
export 'card/card_revision.dart';
|
||||
export 'common/not_found_exception.dart';
|
||||
export 'instance/instance_info.dart';
|
||||
export 'note/note.dart';
|
||||
export 'note/note_revision.dart';
|
||||
export 'review/review_log.dart';
|
||||
export 'settings/person_settings.dart';
|
||||
export 'studyset/studyset.dart';
|
||||
export 'tag/card_tag.dart';
|
||||
export 'tag/note_tag.dart';
|
||||
export 'tag/tag.dart';
|
||||
export 'sync_tables.dart';
|
||||
|
||||
|
|
@ -528,6 +534,319 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
],
|
||||
managed: true,
|
||||
),
|
||||
_isp.TableDefinition(
|
||||
name: 'note',
|
||||
dartName: 'Note',
|
||||
schema: 'public',
|
||||
module: 'halkyon_learn',
|
||||
columns: [
|
||||
_isp.ColumnDefinition(
|
||||
name: 'id',
|
||||
columnType: _isp.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue?',
|
||||
columnDefault: 'random_v7',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'spaceId',
|
||||
columnType: _isp.ColumnType.bigint,
|
||||
isNullable: true,
|
||||
dartType: 'int?',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'studysetId',
|
||||
columnType: _isp.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'position',
|
||||
columnType: _isp.ColumnType.text,
|
||||
isNullable: false,
|
||||
dartType: 'String',
|
||||
),
|
||||
],
|
||||
foreignKeys: [
|
||||
_isp.ForeignKeyDefinition(
|
||||
constraintName: 'note_fk_0',
|
||||
columns: ['spaceId'],
|
||||
referenceTable: 'offline_sync_spaces',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isp.ForeignKeyAction.noAction,
|
||||
onDelete: _isp.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
),
|
||||
_isp.ForeignKeyDefinition(
|
||||
constraintName: 'note_fk_1',
|
||||
columns: ['studysetId'],
|
||||
referenceTable: 'studyset',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isp.ForeignKeyAction.noAction,
|
||||
onDelete: _isp.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
deferrable: _isp.DeferrableConstraint.initiallyDeferred,
|
||||
),
|
||||
],
|
||||
indexes: [
|
||||
_isp.IndexDefinition(
|
||||
indexName: 'note_space_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isp.IndexElementDefinition(
|
||||
type: _isp.IndexElementDefinitionType.column,
|
||||
definition: 'spaceId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
_isp.IndexDefinition(
|
||||
indexName: 'note_studyset_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isp.IndexElementDefinition(
|
||||
type: _isp.IndexElementDefinitionType.column,
|
||||
definition: 'studysetId',
|
||||
),
|
||||
_isp.IndexElementDefinition(
|
||||
type: _isp.IndexElementDefinitionType.column,
|
||||
definition: 'position',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
],
|
||||
managed: true,
|
||||
),
|
||||
_isp.TableDefinition(
|
||||
name: 'note_revision',
|
||||
dartName: 'NoteRevision',
|
||||
schema: 'public',
|
||||
module: 'halkyon_learn',
|
||||
columns: [
|
||||
_isp.ColumnDefinition(
|
||||
name: 'id',
|
||||
columnType: _isp.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue?',
|
||||
columnDefault: 'random_v7',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'spaceId',
|
||||
columnType: _isp.ColumnType.bigint,
|
||||
isNullable: true,
|
||||
dartType: 'int?',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'noteId',
|
||||
columnType: _isp.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'parents',
|
||||
columnType: _isp.ColumnType.json,
|
||||
isNullable: false,
|
||||
dartType: 'List<UuidValue>',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'authorId',
|
||||
columnType: _isp.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'reportId',
|
||||
columnType: _isp.ColumnType.uuid,
|
||||
isNullable: true,
|
||||
dartType: 'UuidValue?',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'keyId',
|
||||
columnType: _isp.ColumnType.text,
|
||||
isNullable: true,
|
||||
dartType: 'String?',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'payload',
|
||||
columnType: _isp.ColumnType.bytea,
|
||||
isNullable: false,
|
||||
dartType: 'dart:typed_data:ByteData',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'nonce',
|
||||
columnType: _isp.ColumnType.bytea,
|
||||
isNullable: true,
|
||||
dartType: 'dart:typed_data:ByteData?',
|
||||
),
|
||||
],
|
||||
foreignKeys: [
|
||||
_isp.ForeignKeyDefinition(
|
||||
constraintName: 'note_revision_fk_0',
|
||||
columns: ['spaceId'],
|
||||
referenceTable: 'offline_sync_spaces',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isp.ForeignKeyAction.noAction,
|
||||
onDelete: _isp.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
),
|
||||
_isp.ForeignKeyDefinition(
|
||||
constraintName: 'note_revision_fk_1',
|
||||
columns: ['noteId'],
|
||||
referenceTable: 'note',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isp.ForeignKeyAction.noAction,
|
||||
onDelete: _isp.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
deferrable: _isp.DeferrableConstraint.initiallyDeferred,
|
||||
),
|
||||
],
|
||||
indexes: [
|
||||
_isp.IndexDefinition(
|
||||
indexName: 'note_revision_space_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isp.IndexElementDefinition(
|
||||
type: _isp.IndexElementDefinitionType.column,
|
||||
definition: 'spaceId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
_isp.IndexDefinition(
|
||||
indexName: 'note_revision_note_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isp.IndexElementDefinition(
|
||||
type: _isp.IndexElementDefinitionType.column,
|
||||
definition: 'noteId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
],
|
||||
managed: true,
|
||||
),
|
||||
_isp.TableDefinition(
|
||||
name: 'note_tag',
|
||||
dartName: 'NoteTag',
|
||||
schema: 'public',
|
||||
module: 'halkyon_learn',
|
||||
columns: [
|
||||
_isp.ColumnDefinition(
|
||||
name: 'id',
|
||||
columnType: _isp.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue?',
|
||||
columnDefault: 'random_v7',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'spaceId',
|
||||
columnType: _isp.ColumnType.bigint,
|
||||
isNullable: true,
|
||||
dartType: 'int?',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'noteId',
|
||||
columnType: _isp.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue',
|
||||
),
|
||||
_isp.ColumnDefinition(
|
||||
name: 'tagId',
|
||||
columnType: _isp.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue',
|
||||
),
|
||||
],
|
||||
foreignKeys: [
|
||||
_isp.ForeignKeyDefinition(
|
||||
constraintName: 'note_tag_fk_0',
|
||||
columns: ['spaceId'],
|
||||
referenceTable: 'offline_sync_spaces',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isp.ForeignKeyAction.noAction,
|
||||
onDelete: _isp.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
),
|
||||
_isp.ForeignKeyDefinition(
|
||||
constraintName: 'note_tag_fk_1',
|
||||
columns: ['noteId'],
|
||||
referenceTable: 'note',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isp.ForeignKeyAction.noAction,
|
||||
onDelete: _isp.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
deferrable: _isp.DeferrableConstraint.initiallyDeferred,
|
||||
),
|
||||
_isp.ForeignKeyDefinition(
|
||||
constraintName: 'note_tag_fk_2',
|
||||
columns: ['tagId'],
|
||||
referenceTable: 'tag',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isp.ForeignKeyAction.noAction,
|
||||
onDelete: _isp.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
deferrable: _isp.DeferrableConstraint.initiallyDeferred,
|
||||
),
|
||||
],
|
||||
indexes: [
|
||||
_isp.IndexDefinition(
|
||||
indexName: 'note_tag_space_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isp.IndexElementDefinition(
|
||||
type: _isp.IndexElementDefinitionType.column,
|
||||
definition: 'spaceId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
_isp.IndexDefinition(
|
||||
indexName: 'note_tag_note_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isp.IndexElementDefinition(
|
||||
type: _isp.IndexElementDefinitionType.column,
|
||||
definition: 'noteId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
_isp.IndexDefinition(
|
||||
indexName: 'note_tag_tag_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isp.IndexElementDefinition(
|
||||
type: _isp.IndexElementDefinitionType.column,
|
||||
definition: 'tagId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
],
|
||||
managed: true,
|
||||
),
|
||||
_isp.TableDefinition(
|
||||
name: 'person_settings',
|
||||
dartName: 'PersonSettings',
|
||||
|
|
@ -962,6 +1281,12 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
if (t == _iskrg2g3.InstanceInfo) {
|
||||
return _iskrg2g3.InstanceInfo.fromJson(data) as T;
|
||||
}
|
||||
if (t == _i9njjhyv.Note) {
|
||||
return _i9njjhyv.Note.fromJson(data) as T;
|
||||
}
|
||||
if (t == _i6j5dng4.NoteRevision) {
|
||||
return _i6j5dng4.NoteRevision.fromJson(data) as T;
|
||||
}
|
||||
if (t == _irzjbdqz.ReviewLog) {
|
||||
return _irzjbdqz.ReviewLog.fromJson(data) as T;
|
||||
}
|
||||
|
|
@ -974,6 +1299,9 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
if (t == _i6jz6nyq.CardTag) {
|
||||
return _i6jz6nyq.CardTag.fromJson(data) as T;
|
||||
}
|
||||
if (t == _itkfn57x.NoteTag) {
|
||||
return _itkfn57x.NoteTag.fromJson(data) as T;
|
||||
}
|
||||
if (t == _ie8t3ar4.Tag) {
|
||||
return _ie8t3ar4.Tag.fromJson(data) as T;
|
||||
}
|
||||
|
|
@ -1021,6 +1349,12 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
if (t == _is.getType<_iskrg2g3.InstanceInfo?>()) {
|
||||
return (data != null ? _iskrg2g3.InstanceInfo.fromJson(data) : null) as T;
|
||||
}
|
||||
if (t == _is.getType<_i9njjhyv.Note?>()) {
|
||||
return (data != null ? _i9njjhyv.Note.fromJson(data) : null) as T;
|
||||
}
|
||||
if (t == _is.getType<_i6j5dng4.NoteRevision?>()) {
|
||||
return (data != null ? _i6j5dng4.NoteRevision.fromJson(data) : null) as T;
|
||||
}
|
||||
if (t == _is.getType<_irzjbdqz.ReviewLog?>()) {
|
||||
return (data != null ? _irzjbdqz.ReviewLog.fromJson(data) : null) as T;
|
||||
}
|
||||
|
|
@ -1034,6 +1368,9 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
if (t == _is.getType<_i6jz6nyq.CardTag?>()) {
|
||||
return (data != null ? _i6jz6nyq.CardTag.fromJson(data) : null) as T;
|
||||
}
|
||||
if (t == _is.getType<_itkfn57x.NoteTag?>()) {
|
||||
return (data != null ? _itkfn57x.NoteTag.fromJson(data) : null) as T;
|
||||
}
|
||||
if (t == _is.getType<_ie8t3ar4.Tag?>()) {
|
||||
return (data != null ? _ie8t3ar4.Tag.fromJson(data) : null) as T;
|
||||
}
|
||||
|
|
@ -1075,10 +1412,13 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
_ipbyuef1.CardRevision => 'CardRevision',
|
||||
_i8oee73b.NotFoundException => 'NotFoundException',
|
||||
_iskrg2g3.InstanceInfo => 'InstanceInfo',
|
||||
_i9njjhyv.Note => 'Note',
|
||||
_i6j5dng4.NoteRevision => 'NoteRevision',
|
||||
_irzjbdqz.ReviewLog => 'ReviewLog',
|
||||
_irnhx5e5.PersonSettings => 'PersonSettings',
|
||||
_ikbclmae.Studyset => 'Studyset',
|
||||
_i6jz6nyq.CardTag => 'CardTag',
|
||||
_itkfn57x.NoteTag => 'NoteTag',
|
||||
_ie8t3ar4.Tag => 'Tag',
|
||||
_ => null,
|
||||
};
|
||||
|
|
@ -1119,6 +1459,10 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
return 'NotFoundException';
|
||||
case _iskrg2g3.InstanceInfo():
|
||||
return 'InstanceInfo';
|
||||
case _i9njjhyv.Note():
|
||||
return 'Note';
|
||||
case _i6j5dng4.NoteRevision():
|
||||
return 'NoteRevision';
|
||||
case _irzjbdqz.ReviewLog():
|
||||
return 'ReviewLog';
|
||||
case _irnhx5e5.PersonSettings():
|
||||
|
|
@ -1127,6 +1471,8 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
return 'Studyset';
|
||||
case _i6jz6nyq.CardTag():
|
||||
return 'CardTag';
|
||||
case _itkfn57x.NoteTag():
|
||||
return 'NoteTag';
|
||||
case _ie8t3ar4.Tag():
|
||||
return 'Tag';
|
||||
}
|
||||
|
|
@ -1194,6 +1540,12 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
if (dataClassName == 'InstanceInfo') {
|
||||
return deserialize<_iskrg2g3.InstanceInfo>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'Note') {
|
||||
return deserialize<_i9njjhyv.Note>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'NoteRevision') {
|
||||
return deserialize<_i6j5dng4.NoteRevision>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'ReviewLog') {
|
||||
return deserialize<_irzjbdqz.ReviewLog>(data['data']);
|
||||
}
|
||||
|
|
@ -1206,6 +1558,9 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
if (dataClassName == 'CardTag') {
|
||||
return deserialize<_i6jz6nyq.CardTag>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'NoteTag') {
|
||||
return deserialize<_itkfn57x.NoteTag>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'Tag') {
|
||||
return deserialize<_ie8t3ar4.Tag>(data['data']);
|
||||
}
|
||||
|
|
@ -1269,6 +1624,10 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
return _ipiw1cmx.Card.t;
|
||||
case _ipbyuef1.CardRevision:
|
||||
return _ipbyuef1.CardRevision.t;
|
||||
case _i9njjhyv.Note:
|
||||
return _i9njjhyv.Note.t;
|
||||
case _i6j5dng4.NoteRevision:
|
||||
return _i6j5dng4.NoteRevision.t;
|
||||
case _irzjbdqz.ReviewLog:
|
||||
return _irzjbdqz.ReviewLog.t;
|
||||
case _irnhx5e5.PersonSettings:
|
||||
|
|
@ -1277,6 +1636,8 @@ class Protocol extends _is.DatabaseSerializationManager {
|
|||
return _ikbclmae.Studyset.t;
|
||||
case _i6jz6nyq.CardTag:
|
||||
return _i6jz6nyq.CardTag.t;
|
||||
case _itkfn57x.NoteTag:
|
||||
return _itkfn57x.NoteTag.t;
|
||||
case _ie8t3ar4.Tag:
|
||||
return _ie8t3ar4.Tag.t;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,13 @@ import 'package:serverpod/serverpod.dart' as _is;
|
|||
import 'asset/asset.dart' as _ipb7vkxr;
|
||||
import 'card/card.dart' as _ipiw1cmx;
|
||||
import 'card/card_revision.dart' as _ipbyuef1;
|
||||
import 'note/note.dart' as _i9njjhyv;
|
||||
import 'note/note_revision.dart' as _i6j5dng4;
|
||||
import 'review/review_log.dart' as _irzjbdqz;
|
||||
import 'settings/person_settings.dart' as _irnhx5e5;
|
||||
import 'studyset/studyset.dart' as _ikbclmae;
|
||||
import 'tag/card_tag.dart' as _i6jz6nyq;
|
||||
import 'tag/note_tag.dart' as _itkfn57x;
|
||||
import 'tag/tag.dart' as _ie8t3ar4;
|
||||
|
||||
/// The tables synchronized between client and server by the
|
||||
|
|
@ -28,6 +31,9 @@ final List<_is.Table> syncTables = [
|
|||
_ipiw1cmx.Card.t,
|
||||
_ipbyuef1.CardRevision.t,
|
||||
_i6jz6nyq.CardTag.t,
|
||||
_i9njjhyv.Note.t,
|
||||
_i6j5dng4.NoteRevision.t,
|
||||
_itkfn57x.NoteTag.t,
|
||||
_irnhx5e5.PersonSettings.t,
|
||||
_irzjbdqz.ReviewLog.t,
|
||||
_ikbclmae.Studyset.t,
|
||||
|
|
|
|||
792
halkyon_learn_server/lib/src/generated/tag/note_tag.dart
Normal file
792
halkyon_learn_server/lib/src/generated/tag/note_tag.dart
Normal file
|
|
@ -0,0 +1,792 @@
|
|||
/* 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, unnecessary_null_comparison
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:halkyon_learn_server/src/generated/protocol.dart' as _i5lsenq5;
|
||||
import 'package:serverpod/serverpod.dart' as _is;
|
||||
import '../note/note.dart' as _iu6jc5sx;
|
||||
import '../tag/tag.dart' as _isqed5gg;
|
||||
|
||||
/// A note having a tag, as CardTag is for cards (ADR 0004): one row per
|
||||
/// assignment, never updated, so concurrent edits merge without losing either;
|
||||
/// a note with the same tag twice counts once. Notes and cards share the
|
||||
/// person's tags. Synced; goes with its note and its tag.
|
||||
abstract class NoteTag
|
||||
implements _is.TableRow<_is.UuidValue?>, _is.ProtocolSerialization {
|
||||
NoteTag._({
|
||||
this.id,
|
||||
this.spaceId,
|
||||
required this.noteId,
|
||||
this.note,
|
||||
required this.tagId,
|
||||
this.tag,
|
||||
});
|
||||
|
||||
factory NoteTag({
|
||||
_is.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _is.UuidValue noteId,
|
||||
_iu6jc5sx.Note? note,
|
||||
required _is.UuidValue tagId,
|
||||
_isqed5gg.Tag? tag,
|
||||
}) = _NoteTagImpl;
|
||||
|
||||
factory NoteTag.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return NoteTag(
|
||||
id: jsonSerialization['id'] == null
|
||||
? null
|
||||
: _is.UuidValueJsonExtension.fromJson(jsonSerialization['id']),
|
||||
spaceId: jsonSerialization['spaceId'] as int?,
|
||||
noteId: _is.UuidValueJsonExtension.fromJson(jsonSerialization['noteId']),
|
||||
note: jsonSerialization['note'] == null
|
||||
? null
|
||||
: _i5lsenq5.Protocol().deserialize<_iu6jc5sx.Note>(
|
||||
jsonSerialization['note'],
|
||||
),
|
||||
tagId: _is.UuidValueJsonExtension.fromJson(jsonSerialization['tagId']),
|
||||
tag: jsonSerialization['tag'] == null
|
||||
? null
|
||||
: _i5lsenq5.Protocol().deserialize<_isqed5gg.Tag>(
|
||||
jsonSerialization['tag'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static final t = NoteTagTable();
|
||||
|
||||
static const db = NoteTagRepository._();
|
||||
|
||||
@override
|
||||
_is.UuidValue? id;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
int? spaceId;
|
||||
|
||||
_is.UuidValue noteId;
|
||||
|
||||
/// The note tagged.
|
||||
_iu6jc5sx.Note? note;
|
||||
|
||||
_is.UuidValue tagId;
|
||||
|
||||
/// The tag it has.
|
||||
_isqed5gg.Tag? tag;
|
||||
|
||||
@override
|
||||
_is.Table<_is.UuidValue?> get table => t;
|
||||
|
||||
/// Returns a shallow copy of this [NoteTag]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_is.useResult
|
||||
NoteTag copyWith({
|
||||
_is.UuidValue? id,
|
||||
int? spaceId,
|
||||
_is.UuidValue? noteId,
|
||||
_iu6jc5sx.Note? note,
|
||||
_is.UuidValue? tagId,
|
||||
_isqed5gg.Tag? tag,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'NoteTag',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'noteId': noteId.toJson(),
|
||||
if (note != null) 'note': note?.toJson(),
|
||||
'tagId': tagId.toJson(),
|
||||
if (tag != null) 'tag': tag?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'NoteTag',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'noteId': noteId.toJson(),
|
||||
if (note != null) 'note': note?.toJsonForProtocol(),
|
||||
'tagId': tagId.toJson(),
|
||||
if (tag != null) 'tag': tag?.toJsonForProtocol(),
|
||||
};
|
||||
}
|
||||
|
||||
static NoteTagInclude include({
|
||||
_iu6jc5sx.NoteInclude? note,
|
||||
_isqed5gg.TagInclude? tag,
|
||||
}) {
|
||||
return NoteTagInclude._(
|
||||
note: note,
|
||||
tag: tag,
|
||||
);
|
||||
}
|
||||
|
||||
static NoteTagIncludeList includeList({
|
||||
_is.WhereExpressionBuilder<NoteTagTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteTagTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTagTable>? orderByList,
|
||||
NoteTagInclude? include,
|
||||
}) {
|
||||
return NoteTagIncludeList._(
|
||||
where: where,
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(NoteTag.t),
|
||||
orderByList: orderByList?.call(NoteTag.t),
|
||||
include: include,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _is.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _NoteTagImpl extends NoteTag {
|
||||
_NoteTagImpl({
|
||||
_is.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _is.UuidValue noteId,
|
||||
_iu6jc5sx.Note? note,
|
||||
required _is.UuidValue tagId,
|
||||
_isqed5gg.Tag? tag,
|
||||
}) : super._(
|
||||
id: id,
|
||||
spaceId: spaceId,
|
||||
noteId: noteId,
|
||||
note: note,
|
||||
tagId: tagId,
|
||||
tag: tag,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [NoteTag]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_is.useResult
|
||||
@override
|
||||
NoteTag copyWith({
|
||||
Object? id = _Undefined,
|
||||
Object? spaceId = _Undefined,
|
||||
_is.UuidValue? noteId,
|
||||
Object? note = _Undefined,
|
||||
_is.UuidValue? tagId,
|
||||
Object? tag = _Undefined,
|
||||
}) {
|
||||
return NoteTag(
|
||||
id: id is _is.UuidValue? ? id : this.id,
|
||||
spaceId: spaceId is int? ? spaceId : this.spaceId,
|
||||
noteId: noteId ?? this.noteId,
|
||||
note: note is _iu6jc5sx.Note? ? note : this.note?.copyWith(),
|
||||
tagId: tagId ?? this.tagId,
|
||||
tag: tag is _isqed5gg.Tag? ? tag : this.tag?.copyWith(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NoteTagUpdateTable extends _is.UpdateTable<NoteTagTable> {
|
||||
NoteTagUpdateTable(super.table);
|
||||
|
||||
_is.ColumnValue<int, int> spaceId(int? value) => _is.ColumnValue(
|
||||
table.spaceId,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<_is.UuidValue, _is.UuidValue> noteId(_is.UuidValue value) =>
|
||||
_is.ColumnValue(
|
||||
table.noteId,
|
||||
value,
|
||||
);
|
||||
|
||||
_is.ColumnValue<_is.UuidValue, _is.UuidValue> tagId(_is.UuidValue value) =>
|
||||
_is.ColumnValue(
|
||||
table.tagId,
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
class NoteTagTable extends _is.Table<_is.UuidValue?> {
|
||||
NoteTagTable({super.tableRelation}) : super(tableName: 'note_tag') {
|
||||
updateTable = NoteTagUpdateTable(this);
|
||||
spaceId = _is.ColumnInt(
|
||||
'spaceId',
|
||||
this,
|
||||
);
|
||||
noteId = _is.ColumnUuid(
|
||||
'noteId',
|
||||
this,
|
||||
);
|
||||
tagId = _is.ColumnUuid(
|
||||
'tagId',
|
||||
this,
|
||||
);
|
||||
}
|
||||
|
||||
late final NoteTagUpdateTable updateTable;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
late final _is.ColumnInt spaceId;
|
||||
|
||||
late final _is.ColumnUuid noteId;
|
||||
|
||||
/// The note tagged.
|
||||
_iu6jc5sx.NoteTable? _note;
|
||||
|
||||
late final _is.ColumnUuid tagId;
|
||||
|
||||
/// The tag it has.
|
||||
_isqed5gg.TagTable? _tag;
|
||||
|
||||
_iu6jc5sx.NoteTable get note {
|
||||
if (_note != null) return _note!;
|
||||
_note = _is.createRelationTable(
|
||||
relationFieldName: 'note',
|
||||
field: NoteTag.t.noteId,
|
||||
foreignField: _iu6jc5sx.Note.t.id,
|
||||
tableRelation: tableRelation,
|
||||
createTable: (foreignTableRelation) =>
|
||||
_iu6jc5sx.NoteTable(tableRelation: foreignTableRelation),
|
||||
);
|
||||
return _note!;
|
||||
}
|
||||
|
||||
_isqed5gg.TagTable get tag {
|
||||
if (_tag != null) return _tag!;
|
||||
_tag = _is.createRelationTable(
|
||||
relationFieldName: 'tag',
|
||||
field: NoteTag.t.tagId,
|
||||
foreignField: _isqed5gg.Tag.t.id,
|
||||
tableRelation: tableRelation,
|
||||
createTable: (foreignTableRelation) =>
|
||||
_isqed5gg.TagTable(tableRelation: foreignTableRelation),
|
||||
);
|
||||
return _tag!;
|
||||
}
|
||||
|
||||
@override
|
||||
List<_is.Column> get columns => [
|
||||
id,
|
||||
spaceId,
|
||||
noteId,
|
||||
tagId,
|
||||
];
|
||||
|
||||
@override
|
||||
_is.Table? getRelationTable(String relationField) {
|
||||
if (relationField == 'note') {
|
||||
return note;
|
||||
}
|
||||
if (relationField == 'tag') {
|
||||
return tag;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class NoteTagInclude extends _is.IncludeObject {
|
||||
NoteTagInclude._({
|
||||
_iu6jc5sx.NoteInclude? note,
|
||||
_isqed5gg.TagInclude? tag,
|
||||
}) {
|
||||
_note = note;
|
||||
_tag = tag;
|
||||
}
|
||||
|
||||
_iu6jc5sx.NoteInclude? _note;
|
||||
|
||||
_isqed5gg.TagInclude? _tag;
|
||||
|
||||
@override
|
||||
Map<String, _is.Include?> get includes => {
|
||||
'note': _note,
|
||||
'tag': _tag,
|
||||
};
|
||||
|
||||
@override
|
||||
_is.Table<_is.UuidValue?> get table => NoteTag.t;
|
||||
}
|
||||
|
||||
class NoteTagIncludeList extends _is.IncludeList {
|
||||
NoteTagIncludeList._({
|
||||
_is.WhereExpressionBuilder<NoteTagTable>? where,
|
||||
super.limit,
|
||||
super.offset,
|
||||
super.orderBy,
|
||||
super.orderByList,
|
||||
super.include,
|
||||
}) {
|
||||
super.where = where?.call(NoteTag.t);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, _is.Include?> get includes => include?.includes ?? {};
|
||||
|
||||
@override
|
||||
_is.Table<_is.UuidValue?> get table => NoteTag.t;
|
||||
}
|
||||
|
||||
class NoteTagRepository {
|
||||
const NoteTagRepository._();
|
||||
|
||||
final attachRow = const NoteTagAttachRowRepository._();
|
||||
|
||||
/// Returns a list of [NoteTag]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<NoteTag>> find(
|
||||
_is.DatabaseSession session, {
|
||||
_is.WhereExpressionBuilder<NoteTagTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteTagTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTagTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
NoteTagInclude? include,
|
||||
_is.LockMode? lockMode,
|
||||
_is.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.find<NoteTag>(
|
||||
where: where?.call(NoteTag.t),
|
||||
orderBy: orderBy?.call(NoteTag.t),
|
||||
orderByList: orderByList?.call(NoteTag.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the first matching [NoteTag] 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<NoteTag?> findFirstRow(
|
||||
_is.DatabaseSession session, {
|
||||
_is.WhereExpressionBuilder<NoteTagTable>? where,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteTagTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTagTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
NoteTagInclude? include,
|
||||
_is.LockMode? lockMode,
|
||||
_is.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findFirstRow<NoteTag>(
|
||||
where: where?.call(NoteTag.t),
|
||||
orderBy: orderBy?.call(NoteTag.t),
|
||||
orderByList: orderByList?.call(NoteTag.t),
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Finds a single [NoteTag] by its [id] or null if no such row exists.
|
||||
Future<NoteTag?> findById(
|
||||
_is.DatabaseSession session,
|
||||
_is.UuidValue id, {
|
||||
_is.Transaction? transaction,
|
||||
NoteTagInclude? include,
|
||||
_is.LockMode? lockMode,
|
||||
_is.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findById<NoteTag>(
|
||||
id,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts all [NoteTag]s in the list and returns the inserted rows.
|
||||
///
|
||||
/// The returned [NoteTag]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<NoteTag>> insert(
|
||||
_is.DatabaseSession session,
|
||||
List<NoteTag> rows, {
|
||||
_is.Transaction? transaction,
|
||||
bool ignoreConflicts = false,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.insert<NoteTag>(
|
||||
rows,
|
||||
transaction: transaction,
|
||||
ignoreConflicts: ignoreConflicts,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts a single [NoteTag] and returns the inserted row.
|
||||
///
|
||||
/// The returned [NoteTag] will have its `id` field set.
|
||||
Future<NoteTag> insertRow(
|
||||
_is.DatabaseSession session,
|
||||
NoteTag row, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.insertRow<NoteTag>(
|
||||
row,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts all [NoteTag]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 [NoteTag]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<NoteTag>> upsert(
|
||||
_is.DatabaseSession session,
|
||||
List<NoteTag> rows, {
|
||||
required _is.ColumnSelections<NoteTagTable> conflictColumns,
|
||||
_is.ColumnSelections<NoteTagTable>? updateColumns,
|
||||
_is.WhereExpressionBuilder<NoteTagTable>? updateWhere,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.upsert<NoteTag>(
|
||||
rows,
|
||||
conflictColumns: conflictColumns(NoteTag.t),
|
||||
updateColumns: updateColumns?.call(NoteTag.t),
|
||||
updateWhere: updateWhere?.call(NoteTag.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts a single [NoteTag] 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 [NoteTag] will have its `id` field set.
|
||||
Future<NoteTag?> upsertRow(
|
||||
_is.DatabaseSession session,
|
||||
NoteTag row, {
|
||||
required _is.ColumnSelections<NoteTagTable> conflictColumns,
|
||||
_is.ColumnSelections<NoteTagTable>? updateColumns,
|
||||
_is.WhereExpressionBuilder<NoteTagTable>? updateWhere,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.upsertRow<NoteTag>(
|
||||
row,
|
||||
conflictColumns: conflictColumns(NoteTag.t),
|
||||
updateColumns: updateColumns?.call(NoteTag.t),
|
||||
updateWhere: updateWhere?.call(NoteTag.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [NoteTag]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<NoteTag>> update(
|
||||
_is.DatabaseSession session,
|
||||
List<NoteTag> rows, {
|
||||
_is.ColumnSelections<NoteTagTable>? columns,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.update<NoteTag>(
|
||||
rows,
|
||||
columns: columns?.call(NoteTag.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [NoteTag]. 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<NoteTag> updateRow(
|
||||
_is.DatabaseSession session,
|
||||
NoteTag row, {
|
||||
_is.ColumnSelections<NoteTagTable>? columns,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateRow<NoteTag>(
|
||||
row,
|
||||
columns: columns?.call(NoteTag.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [NoteTag] by its [id] with the specified [columnValues].
|
||||
/// Returns the updated row or null if no row with the given id exists.
|
||||
Future<NoteTag?> updateById(
|
||||
_is.DatabaseSession session,
|
||||
_is.UuidValue id, {
|
||||
required _is.ColumnValueListBuilder<NoteTagUpdateTable> columnValues,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateById<NoteTag>(
|
||||
id,
|
||||
columnValues: columnValues(NoteTag.t.updateTable),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [NoteTag]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<NoteTag>> updateWhere(
|
||||
_is.DatabaseSession session, {
|
||||
required _is.ColumnValueListBuilder<NoteTagUpdateTable> columnValues,
|
||||
required _is.WhereExpressionBuilder<NoteTagTable> where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_is.OrderByBuilder<NoteTagTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTagTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.updateWhere<NoteTag>(
|
||||
columnValues: columnValues(NoteTag.t.updateTable),
|
||||
where: where(NoteTag.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(NoteTag.t),
|
||||
orderByList: orderByList?.call(NoteTag.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes all [NoteTag]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<NoteTag>> delete(
|
||||
_is.DatabaseSession session,
|
||||
List<NoteTag> rows, {
|
||||
_is.OrderByBuilder<NoteTagTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTagTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.delete<NoteTag>(
|
||||
rows,
|
||||
orderBy: orderBy?.call(NoteTag.t),
|
||||
orderByList: orderByList?.call(NoteTag.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes a single [NoteTag].
|
||||
Future<NoteTag> deleteRow(
|
||||
_is.DatabaseSession session,
|
||||
NoteTag row, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.deleteRow<NoteTag>(
|
||||
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<NoteTag>> deleteWhere(
|
||||
_is.DatabaseSession session, {
|
||||
required _is.WhereExpressionBuilder<NoteTagTable> where,
|
||||
_is.OrderByBuilder<NoteTagTable>? orderBy,
|
||||
_is.OrderByListBuilder<NoteTagTable>? orderByList,
|
||||
_is.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.deleteWhere<NoteTag>(
|
||||
where: where(NoteTag.t),
|
||||
orderBy: orderBy?.call(NoteTag.t),
|
||||
orderByList: orderByList?.call(NoteTag.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<NoteTagTable>? where,
|
||||
int? limit,
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.count<NoteTag>(
|
||||
where: where?.call(NoteTag.t),
|
||||
limit: limit,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Acquires row-level locks on [NoteTag] rows matching the [where] expression.
|
||||
Future<void> lockRows(
|
||||
_is.DatabaseSession session, {
|
||||
required _is.WhereExpressionBuilder<NoteTagTable> where,
|
||||
required _is.LockMode lockMode,
|
||||
required _is.Transaction transaction,
|
||||
_is.LockBehavior lockBehavior = _is.LockBehavior.wait,
|
||||
}) async {
|
||||
return session.db.lockRows<NoteTag>(
|
||||
where: where(NoteTag.t),
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NoteTagAttachRowRepository {
|
||||
const NoteTagAttachRowRepository._();
|
||||
|
||||
/// Creates a relation between the given [NoteTag] and [Note]
|
||||
/// by setting the [NoteTag]'s foreign key `noteId` to refer to the [Note].
|
||||
Future<void> note(
|
||||
_is.DatabaseSession session,
|
||||
NoteTag noteTag,
|
||||
_iu6jc5sx.Note note, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
if (noteTag.id == null) {
|
||||
throw ArgumentError.notNull('noteTag.id');
|
||||
}
|
||||
if (note.id == null) {
|
||||
throw ArgumentError.notNull('note.id');
|
||||
}
|
||||
|
||||
var $noteTag = noteTag.copyWith(noteId: note.id);
|
||||
await session.db.updateRow<NoteTag>(
|
||||
$noteTag,
|
||||
columns: [NoteTag.t.noteId],
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a relation between the given [NoteTag] and [Tag]
|
||||
/// by setting the [NoteTag]'s foreign key `tagId` to refer to the [Tag].
|
||||
Future<void> tag(
|
||||
_is.DatabaseSession session,
|
||||
NoteTag noteTag,
|
||||
_isqed5gg.Tag tag, {
|
||||
_is.Transaction? transaction,
|
||||
}) async {
|
||||
if (noteTag.id == null) {
|
||||
throw ArgumentError.notNull('noteTag.id');
|
||||
}
|
||||
if (tag.id == null) {
|
||||
throw ArgumentError.notNull('tag.id');
|
||||
}
|
||||
|
||||
var $noteTag = noteTag.copyWith(tagId: tag.id);
|
||||
await session.db.updateRow<NoteTag>(
|
||||
$noteTag,
|
||||
columns: [NoteTag.t.tagId],
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
19
halkyon_learn_server/lib/src/note/note.spy.yaml
Normal file
19
halkyon_learn_server/lib/src/note/note.spy.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
### A note in a studyset: rich text the person writes and reads, never studied.
|
||||
### Its content lives in its revisions (NoteRevision), never in this row: content
|
||||
### is append-only (ADR 0001, rule 2), as a card's is. Synced; its space owns it.
|
||||
class: Note
|
||||
table: note
|
||||
database: sync
|
||||
fields:
|
||||
### The studyset the note belongs to; the note goes with it.
|
||||
studyset: Studyset?, relation(onDelete=Cascade, deferred)
|
||||
### Where the note stands among its studyset's notes: a fractional index, as a
|
||||
### card's position; last writer wins.
|
||||
position: String
|
||||
indexes:
|
||||
# Deleting a space finds its rows through this index (see studyset.spy.yaml).
|
||||
note_space_idx:
|
||||
fields: spaceId
|
||||
# A studyset's notes, in order.
|
||||
note_studyset_idx:
|
||||
fields: studysetId, position
|
||||
32
halkyon_learn_server/lib/src/note/note_revision.spy.yaml
Normal file
32
halkyon_learn_server/lib/src/note/note_revision.spy.yaml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
### One version of a note's content, never changed once written (ADR 0001,
|
||||
### rule 2), merged as a card's revisions are (ADR 0003): editing appends a
|
||||
### revision whose parents are the versions the edit started from, and a note's
|
||||
### current versions are the revisions no other replaces. Deleting a note blanks
|
||||
### every revision's payload first (ADR 0002, rule 2).
|
||||
class: NoteRevision
|
||||
table: note_revision
|
||||
database: sync
|
||||
fields:
|
||||
### The note this is a version of; its revisions go with it.
|
||||
note: Note?, relation(onDelete=Cascade, deferred)
|
||||
### The revisions this one replaces: none for a note's first, several when it
|
||||
### resolves a conflict. Plain ids, since revisions can arrive in any order.
|
||||
parents: List<UuidValue>
|
||||
### Who wrote it: the AuthUser's id (a synced table can't relate to the
|
||||
### server-only AuthUser).
|
||||
authorId: UuidValue
|
||||
### The report this revision answers, once reports exist; null otherwise.
|
||||
reportId: UuidValue?
|
||||
### The encryption key's id; always null (ADR 0002, rule 6).
|
||||
keyId: String?
|
||||
### The content as UTF-8 JSON: {"schemaVersion", "title", "body"}.
|
||||
payload: ByteData
|
||||
### The encryption nonce; always null, like keyId.
|
||||
nonce: ByteData?
|
||||
indexes:
|
||||
# Deleting a space finds its rows through this index (see studyset.spy.yaml).
|
||||
note_revision_space_idx:
|
||||
fields: spaceId
|
||||
# A note's revisions.
|
||||
note_revision_note_idx:
|
||||
fields: noteId
|
||||
22
halkyon_learn_server/lib/src/tag/note_tag.spy.yaml
Normal file
22
halkyon_learn_server/lib/src/tag/note_tag.spy.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
### A note having a tag, as CardTag is for cards (ADR 0004): one row per
|
||||
### assignment, never updated, so concurrent edits merge without losing either;
|
||||
### a note with the same tag twice counts once. Notes and cards share the
|
||||
### person's tags. Synced; goes with its note and its tag.
|
||||
class: NoteTag
|
||||
table: note_tag
|
||||
database: sync
|
||||
fields:
|
||||
### The note tagged.
|
||||
note: Note?, relation(onDelete=Cascade, deferred)
|
||||
### The tag it has.
|
||||
tag: Tag?, relation(onDelete=Cascade, deferred)
|
||||
indexes:
|
||||
# Deleting a space finds its rows through this index (see studyset.spy.yaml).
|
||||
note_tag_space_idx:
|
||||
fields: spaceId
|
||||
# A note's tags.
|
||||
note_tag_note_idx:
|
||||
fields: noteId
|
||||
# A tag's notes.
|
||||
note_tag_tag_idx:
|
||||
fields: tagId
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,405 @@
|
|||
{
|
||||
"__className__": "serverpod.DatabaseMigration",
|
||||
"actions": [
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationAction",
|
||||
"type": "createTable",
|
||||
"createTable": {
|
||||
"__className__": "serverpod.TableDefinition",
|
||||
"name": "note",
|
||||
"dartName": "Note",
|
||||
"module": "halkyon_learn",
|
||||
"schema": "public",
|
||||
"columns": [
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "id",
|
||||
"fieldName": "id",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"columnDefault": "random_v7",
|
||||
"dartType": "UuidValue?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "spaceId",
|
||||
"fieldName": "spaceId",
|
||||
"columnType": 6,
|
||||
"isNullable": true,
|
||||
"dartType": "int?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "studysetId",
|
||||
"fieldName": "studysetId",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"dartType": "UuidValue"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "position",
|
||||
"fieldName": "position",
|
||||
"columnType": 0,
|
||||
"isNullable": false,
|
||||
"dartType": "String"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "note_fk_0",
|
||||
"columns": [
|
||||
"spaceId"
|
||||
],
|
||||
"referenceTable": "offline_sync_spaces",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "note_fk_1",
|
||||
"columns": [
|
||||
"studysetId"
|
||||
],
|
||||
"referenceTable": "studyset",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4,
|
||||
"deferrable": "initiallyDeferred"
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "note_space_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "spaceId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "note_studyset_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "studysetId"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "position"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
}
|
||||
],
|
||||
"managed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationAction",
|
||||
"type": "createTable",
|
||||
"createTable": {
|
||||
"__className__": "serverpod.TableDefinition",
|
||||
"name": "note_revision",
|
||||
"dartName": "NoteRevision",
|
||||
"module": "halkyon_learn",
|
||||
"schema": "public",
|
||||
"columns": [
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "id",
|
||||
"fieldName": "id",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"columnDefault": "random_v7",
|
||||
"dartType": "UuidValue?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "spaceId",
|
||||
"fieldName": "spaceId",
|
||||
"columnType": 6,
|
||||
"isNullable": true,
|
||||
"dartType": "int?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "noteId",
|
||||
"fieldName": "noteId",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"dartType": "UuidValue"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "parents",
|
||||
"fieldName": "parents",
|
||||
"columnType": 8,
|
||||
"isNullable": false,
|
||||
"dartType": "List<UuidValue>"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "authorId",
|
||||
"fieldName": "authorId",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"dartType": "UuidValue"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "reportId",
|
||||
"fieldName": "reportId",
|
||||
"columnType": 7,
|
||||
"isNullable": true,
|
||||
"dartType": "UuidValue?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "keyId",
|
||||
"fieldName": "keyId",
|
||||
"columnType": 0,
|
||||
"isNullable": true,
|
||||
"dartType": "String?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "payload",
|
||||
"fieldName": "payload",
|
||||
"columnType": 5,
|
||||
"isNullable": false,
|
||||
"dartType": "dart:typed_data:ByteData"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "nonce",
|
||||
"fieldName": "nonce",
|
||||
"columnType": 5,
|
||||
"isNullable": true,
|
||||
"dartType": "dart:typed_data:ByteData?"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "note_revision_fk_0",
|
||||
"columns": [
|
||||
"spaceId"
|
||||
],
|
||||
"referenceTable": "offline_sync_spaces",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "note_revision_fk_1",
|
||||
"columns": [
|
||||
"noteId"
|
||||
],
|
||||
"referenceTable": "note",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4,
|
||||
"deferrable": "initiallyDeferred"
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "note_revision_space_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "spaceId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "note_revision_note_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "noteId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
}
|
||||
],
|
||||
"managed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationAction",
|
||||
"type": "createTable",
|
||||
"createTable": {
|
||||
"__className__": "serverpod.TableDefinition",
|
||||
"name": "note_tag",
|
||||
"dartName": "NoteTag",
|
||||
"module": "halkyon_learn",
|
||||
"schema": "public",
|
||||
"columns": [
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "id",
|
||||
"fieldName": "id",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"columnDefault": "random_v7",
|
||||
"dartType": "UuidValue?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "spaceId",
|
||||
"fieldName": "spaceId",
|
||||
"columnType": 6,
|
||||
"isNullable": true,
|
||||
"dartType": "int?"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "noteId",
|
||||
"fieldName": "noteId",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"dartType": "UuidValue"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "tagId",
|
||||
"fieldName": "tagId",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"dartType": "UuidValue"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "note_tag_fk_0",
|
||||
"columns": [
|
||||
"spaceId"
|
||||
],
|
||||
"referenceTable": "offline_sync_spaces",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "note_tag_fk_1",
|
||||
"columns": [
|
||||
"noteId"
|
||||
],
|
||||
"referenceTable": "note",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4,
|
||||
"deferrable": "initiallyDeferred"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "note_tag_fk_2",
|
||||
"columns": [
|
||||
"tagId"
|
||||
],
|
||||
"referenceTable": "tag",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4,
|
||||
"deferrable": "initiallyDeferred"
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "note_tag_space_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "spaceId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "note_tag_note_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "noteId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "note_tag_tag_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "tagId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
}
|
||||
],
|
||||
"managed": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"warnings": [],
|
||||
"migrationApiVersion": 1
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
BEGIN;
|
||||
|
||||
--
|
||||
-- Function: gen_random_uuid_v7()
|
||||
-- Source: https://gist.github.com/kjmph/5bd772b2c2df145aa645b837da7eca74
|
||||
-- License: MIT (copyright notice included on the generator source code).
|
||||
--
|
||||
create or replace function gen_random_uuid_v7()
|
||||
returns uuid
|
||||
as $$
|
||||
begin
|
||||
-- use random v4 uuid as starting point (which has the same variant we need)
|
||||
-- then overlay timestamp
|
||||
-- then set version 7 by flipping the 2 and 1 bit in the version 4 string
|
||||
return encode(
|
||||
set_bit(
|
||||
set_bit(
|
||||
overlay(uuid_send(gen_random_uuid())
|
||||
placing substring(int8send(floor(extract(epoch from clock_timestamp()) * 1000)::bigint) from 3)
|
||||
from 1 for 6
|
||||
),
|
||||
52, 1
|
||||
),
|
||||
53, 1
|
||||
),
|
||||
'hex')::uuid;
|
||||
end
|
||||
$$
|
||||
language plpgsql
|
||||
volatile;
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "note" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid_v7(),
|
||||
"spaceId" bigint,
|
||||
"studysetId" uuid NOT NULL,
|
||||
"position" text NOT NULL
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX "note_space_idx" ON "note" USING btree ("spaceId");
|
||||
CREATE INDEX "note_studyset_idx" ON "note" USING btree ("studysetId", "position");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "note_revision" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid_v7(),
|
||||
"spaceId" bigint,
|
||||
"noteId" uuid NOT NULL,
|
||||
"parents" json NOT NULL,
|
||||
"authorId" uuid NOT NULL,
|
||||
"reportId" uuid,
|
||||
"keyId" text,
|
||||
"payload" bytea NOT NULL,
|
||||
"nonce" bytea
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX "note_revision_space_idx" ON "note_revision" USING btree ("spaceId");
|
||||
CREATE INDEX "note_revision_note_idx" ON "note_revision" USING btree ("noteId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE TABLE
|
||||
--
|
||||
CREATE TABLE "note_tag" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid_v7(),
|
||||
"spaceId" bigint,
|
||||
"noteId" uuid NOT NULL,
|
||||
"tagId" uuid NOT NULL
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX "note_tag_space_idx" ON "note_tag" USING btree ("spaceId");
|
||||
CREATE INDEX "note_tag_note_idx" ON "note_tag" USING btree ("noteId");
|
||||
CREATE INDEX "note_tag_tag_idx" ON "note_tag" USING btree ("tagId");
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "note"
|
||||
ADD CONSTRAINT "note_fk_0"
|
||||
FOREIGN KEY("spaceId")
|
||||
REFERENCES "offline_sync_spaces"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
ALTER TABLE ONLY "note"
|
||||
ADD CONSTRAINT "note_fk_1"
|
||||
FOREIGN KEY("studysetId")
|
||||
REFERENCES "studyset"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "note_revision"
|
||||
ADD CONSTRAINT "note_revision_fk_0"
|
||||
FOREIGN KEY("spaceId")
|
||||
REFERENCES "offline_sync_spaces"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
ALTER TABLE ONLY "note_revision"
|
||||
ADD CONSTRAINT "note_revision_fk_1"
|
||||
FOREIGN KEY("noteId")
|
||||
REFERENCES "note"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
--
|
||||
-- ACTION CREATE FOREIGN KEY
|
||||
--
|
||||
ALTER TABLE ONLY "note_tag"
|
||||
ADD CONSTRAINT "note_tag_fk_0"
|
||||
FOREIGN KEY("spaceId")
|
||||
REFERENCES "offline_sync_spaces"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION;
|
||||
ALTER TABLE ONLY "note_tag"
|
||||
ADD CONSTRAINT "note_tag_fk_1"
|
||||
FOREIGN KEY("noteId")
|
||||
REFERENCES "note"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
||||
ALTER TABLE ONLY "note_tag"
|
||||
ADD CONSTRAINT "note_tag_fk_2"
|
||||
FOREIGN KEY("tagId")
|
||||
REFERENCES "tag"("id")
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR halkyon_learn
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('halkyon_learn', '20261002191122122-notes', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20261002191122122-notes', "timestamp" = now();
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR serverpod
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('serverpod', '20260824182259319', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20260824182259319', "timestamp" = now();
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR serverpod_auth_idp
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('serverpod_auth_idp', '20260924105404509', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20260924105404509', "timestamp" = now();
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR serverpod_offline_sync
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('serverpod_offline_sync', '20260914143806119', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20260914143806119', "timestamp" = now();
|
||||
|
||||
--
|
||||
-- MIGRATION VERSION FOR serverpod_auth_core
|
||||
--
|
||||
INSERT INTO "serverpod_migrations" ("module", "version", "timestamp")
|
||||
VALUES ('serverpod_auth_core', '20260924105232991', now())
|
||||
ON CONFLICT ("module")
|
||||
DO UPDATE SET "version" = '20260924105232991', "timestamp" = now();
|
||||
|
||||
|
||||
COMMIT;
|
||||
|
|
@ -10,3 +10,4 @@
|
|||
20260930145136285-reviews
|
||||
20261001064926911-tree-tags-assets
|
||||
20261002035419149-file-allowance
|
||||
20261002191122122-notes
|
||||
|
|
|
|||
Loading…
Reference in a new issue