feat: PDF sources: read, take notes and cards from pages, deadlines
PDFs live in a studyset's new Files tab: uploaded from Add material (a file the studyset holds already asks first), each row with its pages, cards, notes and size, how far it is read and its reading deadline; renamed, given a deadline (a page or a chapter by a day), marked as read, started afresh, deleted with a moment to undo. The reader (/pdfs/:id) opens where reading left off: on wide windows a rail of tools (search, fit, zoom, fullscreen), a page counter with the chapter, and a sidebar; on phones a top bar, a page scrubber and a sheet. The sidebar holds the PDF's flashcards, by page or chapter, made from selected text or written there, each tied to its page and tagged with its chapter; and the page's note, an ordinary note tied to the page. Screenshots of a region become images that know their page. Cards and screenshots lead back to their page; reading on past a chapter with cards suggests studying it. Home shows the deadlines running and to come, and a timeline of them. Server: pdf_source rows (content in the payload, last writer wins) and an append-only pdf_reading log, the furthest page derived from it so devices never conflict. Files up to 50 MB for PDFs (20 MB for others; a larger file that isn't a PDF is deleted once stored). A deleted PDF takes its file's asset row along unless another PDF has the same file. Card payload 4 and note payload 2 keep the page. The reader draws with pdfrx (PDFium) behind PdfEngine in Dependencies; widget tests use a fake, and integration_test/pdf_engine_test.dart checks the real engine on a device or the desktop. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
ec34bb2334
commit
b96db731c1
9 changed files with 34926 additions and 58 deletions
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,260 @@
|
|||
{
|
||||
"__className__": "serverpod.DatabaseMigration",
|
||||
"actions": [
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationAction",
|
||||
"type": "createTable",
|
||||
"createTable": {
|
||||
"__className__": "serverpod.TableDefinition",
|
||||
"name": "pdf_reading",
|
||||
"dartName": "PdfReading",
|
||||
"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": "pdfSourceId",
|
||||
"fieldName": "pdfSourceId",
|
||||
"columnType": 7,
|
||||
"isNullable": false,
|
||||
"dartType": "UuidValue"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "readAt",
|
||||
"fieldName": "readAt",
|
||||
"columnType": 4,
|
||||
"isNullable": false,
|
||||
"dartType": "DateTime"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "kind",
|
||||
"fieldName": "kind",
|
||||
"columnType": 0,
|
||||
"isNullable": false,
|
||||
"dartType": "String"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ColumnDefinition",
|
||||
"name": "page",
|
||||
"fieldName": "page",
|
||||
"columnType": 6,
|
||||
"isNullable": false,
|
||||
"dartType": "int"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "pdf_reading_fk_0",
|
||||
"columns": [
|
||||
"spaceId"
|
||||
],
|
||||
"referenceTable": "offline_sync_spaces",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "pdf_reading_fk_1",
|
||||
"columns": [
|
||||
"pdfSourceId"
|
||||
],
|
||||
"referenceTable": "pdf_source",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4,
|
||||
"deferrable": "initiallyDeferred"
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "pdf_reading_space_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "spaceId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "pdf_reading_source_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "pdfSourceId"
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "readAt"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
}
|
||||
],
|
||||
"managed": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.DatabaseMigrationAction",
|
||||
"type": "createTable",
|
||||
"createTable": {
|
||||
"__className__": "serverpod.TableDefinition",
|
||||
"name": "pdf_source",
|
||||
"dartName": "PdfSource",
|
||||
"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": "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": "pdf_source_fk_0",
|
||||
"columns": [
|
||||
"spaceId"
|
||||
],
|
||||
"referenceTable": "offline_sync_spaces",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.ForeignKeyDefinition",
|
||||
"constraintName": "pdf_source_fk_1",
|
||||
"columns": [
|
||||
"studysetId"
|
||||
],
|
||||
"referenceTable": "studyset",
|
||||
"referenceTableSchema": "public",
|
||||
"referenceColumns": [
|
||||
"id"
|
||||
],
|
||||
"onUpdate": 3,
|
||||
"onDelete": 4,
|
||||
"deferrable": "initiallyDeferred"
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "pdf_source_space_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "spaceId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
},
|
||||
{
|
||||
"__className__": "serverpod.IndexDefinition",
|
||||
"indexName": "pdf_source_studyset_idx",
|
||||
"elements": [
|
||||
{
|
||||
"__className__": "serverpod.IndexElementDefinition",
|
||||
"type": 0,
|
||||
"definition": "studysetId"
|
||||
}
|
||||
],
|
||||
"type": "btree",
|
||||
"isUnique": false,
|
||||
"isPrimary": false
|
||||
}
|
||||
],
|
||||
"managed": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"warnings": [],
|
||||
"migrationApiVersion": 1
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ part '20260930145136285-reviews/migration.dart';
|
|||
part '20261001064926911-tree-tags-assets/migration.dart';
|
||||
part '20261002191122122-notes/migration.dart';
|
||||
part '20261002211346701-learning-paths/migration.dart';
|
||||
part '20261003110855698-pdf-sources/migration.dart';
|
||||
|
||||
/// Migration registry for the client-side database.
|
||||
class MigrationRegistry {
|
||||
|
|
@ -22,6 +23,7 @@ class MigrationRegistry {
|
|||
_Migration20261001064926911_tree_tags_assets(),
|
||||
_Migration20261002191122122_notes(),
|
||||
_Migration20261002211346701_learning_paths(),
|
||||
_Migration20261003110855698_pdf_sources(),
|
||||
];
|
||||
|
||||
/// List of all client-side database migration versions.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,782 @@
|
|||
/* 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_client/src/protocol/protocol.dart' as _itx5j3f5;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import 'package:serverpod_database/serverpod_database.dart' as _isd;
|
||||
import '../pdf_source/pdf_source.dart' as _ijdmmu1w;
|
||||
|
||||
/// How far a PDF has been read, as an entry that is never changed once written:
|
||||
/// the furthest page isn't stored but derived from these, as a card's schedule
|
||||
/// is from its reviews, so reading on two devices never conflicts. An entry is
|
||||
/// written only when the furthest page grows, so a PDF has at most an entry per
|
||||
/// page per fresh start. Synced; the entry goes with its PDF.
|
||||
abstract class PdfReading
|
||||
implements _isd.TableRow<_isc.UuidValue?>, _isc.ProtocolSerialization {
|
||||
PdfReading._({
|
||||
this.id,
|
||||
this.spaceId,
|
||||
required this.pdfSourceId,
|
||||
this.pdfSource,
|
||||
required this.readAt,
|
||||
required this.kind,
|
||||
required this.page,
|
||||
});
|
||||
|
||||
factory PdfReading({
|
||||
_isc.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _isc.UuidValue pdfSourceId,
|
||||
_ijdmmu1w.PdfSource? pdfSource,
|
||||
required DateTime readAt,
|
||||
required String kind,
|
||||
required int page,
|
||||
}) = _PdfReadingImpl;
|
||||
|
||||
factory PdfReading.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return PdfReading(
|
||||
id: jsonSerialization['id'] == null
|
||||
? null
|
||||
: _isc.UuidValueJsonExtension.fromJson(jsonSerialization['id']),
|
||||
spaceId: jsonSerialization['spaceId'] as int?,
|
||||
pdfSourceId: _isc.UuidValueJsonExtension.fromJson(
|
||||
jsonSerialization['pdfSourceId'],
|
||||
),
|
||||
pdfSource: jsonSerialization['pdfSource'] == null
|
||||
? null
|
||||
: _itx5j3f5.Protocol().deserialize<_ijdmmu1w.PdfSource>(
|
||||
jsonSerialization['pdfSource'],
|
||||
),
|
||||
readAt: _isc.DateTimeJsonExtension.fromJson(jsonSerialization['readAt']),
|
||||
kind: jsonSerialization['kind'] as String,
|
||||
page: jsonSerialization['page'] as int,
|
||||
);
|
||||
}
|
||||
|
||||
static final t = PdfReadingTable();
|
||||
|
||||
static const db = PdfReadingRepository._();
|
||||
|
||||
@override
|
||||
_isc.UuidValue? id;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
int? spaceId;
|
||||
|
||||
_isc.UuidValue pdfSourceId;
|
||||
|
||||
/// The PDF read.
|
||||
_ijdmmu1w.PdfSource? pdfSource;
|
||||
|
||||
/// When, in UTC.
|
||||
DateTime readAt;
|
||||
|
||||
/// 'reached' for a page reached (marking the PDF finished reaches its last
|
||||
/// page); 'reset' for a fresh start: the furthest page is the furthest
|
||||
/// reached since the last one.
|
||||
String kind;
|
||||
|
||||
/// The page reached, from 1; 0 for 'reset'.
|
||||
int page;
|
||||
|
||||
@override
|
||||
_isd.Table<_isc.UuidValue?> get table => t;
|
||||
|
||||
/// Returns a shallow copy of this [PdfReading]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
PdfReading copyWith({
|
||||
_isc.UuidValue? id,
|
||||
int? spaceId,
|
||||
_isc.UuidValue? pdfSourceId,
|
||||
_ijdmmu1w.PdfSource? pdfSource,
|
||||
DateTime? readAt,
|
||||
String? kind,
|
||||
int? page,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'PdfReading',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'pdfSourceId': pdfSourceId.toJson(),
|
||||
if (pdfSource != null) 'pdfSource': pdfSource?.toJson(),
|
||||
'readAt': readAt.toJson(),
|
||||
'kind': kind,
|
||||
'page': page,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'PdfReading',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'pdfSourceId': pdfSourceId.toJson(),
|
||||
if (pdfSource != null) 'pdfSource': pdfSource?.toJsonForProtocol(),
|
||||
'readAt': readAt.toJson(),
|
||||
'kind': kind,
|
||||
'page': page,
|
||||
};
|
||||
}
|
||||
|
||||
static PdfReadingInclude include({_ijdmmu1w.PdfSourceInclude? pdfSource}) {
|
||||
return PdfReadingInclude._(pdfSource: pdfSource);
|
||||
}
|
||||
|
||||
static PdfReadingIncludeList includeList({
|
||||
_isd.WhereExpressionBuilder<PdfReadingTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_isd.OrderByBuilder<PdfReadingTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfReadingTable>? orderByList,
|
||||
PdfReadingInclude? include,
|
||||
}) {
|
||||
return PdfReadingIncludeList._(
|
||||
where: where,
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(PdfReading.t),
|
||||
orderByList: orderByList?.call(PdfReading.t),
|
||||
include: include,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _PdfReadingImpl extends PdfReading {
|
||||
_PdfReadingImpl({
|
||||
_isc.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _isc.UuidValue pdfSourceId,
|
||||
_ijdmmu1w.PdfSource? pdfSource,
|
||||
required DateTime readAt,
|
||||
required String kind,
|
||||
required int page,
|
||||
}) : super._(
|
||||
id: id,
|
||||
spaceId: spaceId,
|
||||
pdfSourceId: pdfSourceId,
|
||||
pdfSource: pdfSource,
|
||||
readAt: readAt,
|
||||
kind: kind,
|
||||
page: page,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [PdfReading]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
PdfReading copyWith({
|
||||
Object? id = _Undefined,
|
||||
Object? spaceId = _Undefined,
|
||||
_isc.UuidValue? pdfSourceId,
|
||||
Object? pdfSource = _Undefined,
|
||||
DateTime? readAt,
|
||||
String? kind,
|
||||
int? page,
|
||||
}) {
|
||||
return PdfReading(
|
||||
id: id is _isc.UuidValue? ? id : this.id,
|
||||
spaceId: spaceId is int? ? spaceId : this.spaceId,
|
||||
pdfSourceId: pdfSourceId ?? this.pdfSourceId,
|
||||
pdfSource: pdfSource is _ijdmmu1w.PdfSource?
|
||||
? pdfSource
|
||||
: this.pdfSource?.copyWith(),
|
||||
readAt: readAt ?? this.readAt,
|
||||
kind: kind ?? this.kind,
|
||||
page: page ?? this.page,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PdfReadingUpdateTable extends _isd.UpdateTable<PdfReadingTable> {
|
||||
PdfReadingUpdateTable(super.table);
|
||||
|
||||
_isd.ColumnValue<int, int> spaceId(int? value) => _isd.ColumnValue(
|
||||
table.spaceId,
|
||||
value,
|
||||
);
|
||||
|
||||
_isd.ColumnValue<_isc.UuidValue, _isc.UuidValue> pdfSourceId(
|
||||
_isc.UuidValue value,
|
||||
) => _isd.ColumnValue(
|
||||
table.pdfSourceId,
|
||||
value,
|
||||
);
|
||||
|
||||
_isd.ColumnValue<DateTime, DateTime> readAt(DateTime value) =>
|
||||
_isd.ColumnValue(
|
||||
table.readAt,
|
||||
value,
|
||||
);
|
||||
|
||||
_isd.ColumnValue<String, String> kind(String value) => _isd.ColumnValue(
|
||||
table.kind,
|
||||
value,
|
||||
);
|
||||
|
||||
_isd.ColumnValue<int, int> page(int value) => _isd.ColumnValue(
|
||||
table.page,
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
class PdfReadingTable extends _isd.Table<_isc.UuidValue?> {
|
||||
PdfReadingTable({super.tableRelation}) : super(tableName: 'pdf_reading') {
|
||||
updateTable = PdfReadingUpdateTable(this);
|
||||
spaceId = _isd.ColumnInt(
|
||||
'spaceId',
|
||||
this,
|
||||
);
|
||||
pdfSourceId = _isd.ColumnUuid(
|
||||
'pdfSourceId',
|
||||
this,
|
||||
);
|
||||
readAt = _isd.ColumnDateTime(
|
||||
'readAt',
|
||||
this,
|
||||
);
|
||||
kind = _isd.ColumnString(
|
||||
'kind',
|
||||
this,
|
||||
);
|
||||
page = _isd.ColumnInt(
|
||||
'page',
|
||||
this,
|
||||
);
|
||||
}
|
||||
|
||||
late final PdfReadingUpdateTable updateTable;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
late final _isd.ColumnInt spaceId;
|
||||
|
||||
late final _isd.ColumnUuid pdfSourceId;
|
||||
|
||||
/// The PDF read.
|
||||
_ijdmmu1w.PdfSourceTable? _pdfSource;
|
||||
|
||||
/// When, in UTC.
|
||||
late final _isd.ColumnDateTime readAt;
|
||||
|
||||
/// 'reached' for a page reached (marking the PDF finished reaches its last
|
||||
/// page); 'reset' for a fresh start: the furthest page is the furthest
|
||||
/// reached since the last one.
|
||||
late final _isd.ColumnString kind;
|
||||
|
||||
/// The page reached, from 1; 0 for 'reset'.
|
||||
late final _isd.ColumnInt page;
|
||||
|
||||
_ijdmmu1w.PdfSourceTable get pdfSource {
|
||||
if (_pdfSource != null) return _pdfSource!;
|
||||
_pdfSource = _isd.createRelationTable(
|
||||
relationFieldName: 'pdfSource',
|
||||
field: PdfReading.t.pdfSourceId,
|
||||
foreignField: _ijdmmu1w.PdfSource.t.id,
|
||||
tableRelation: tableRelation,
|
||||
createTable: (foreignTableRelation) =>
|
||||
_ijdmmu1w.PdfSourceTable(tableRelation: foreignTableRelation),
|
||||
);
|
||||
return _pdfSource!;
|
||||
}
|
||||
|
||||
@override
|
||||
List<_isd.Column> get columns => [
|
||||
id,
|
||||
spaceId,
|
||||
pdfSourceId,
|
||||
readAt,
|
||||
kind,
|
||||
page,
|
||||
];
|
||||
|
||||
@override
|
||||
_isd.Table? getRelationTable(String relationField) {
|
||||
if (relationField == 'pdfSource') {
|
||||
return pdfSource;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class PdfReadingInclude extends _isd.IncludeObject {
|
||||
PdfReadingInclude._({_ijdmmu1w.PdfSourceInclude? pdfSource}) {
|
||||
_pdfSource = pdfSource;
|
||||
}
|
||||
|
||||
_ijdmmu1w.PdfSourceInclude? _pdfSource;
|
||||
|
||||
@override
|
||||
Map<String, _isd.Include?> get includes => {'pdfSource': _pdfSource};
|
||||
|
||||
@override
|
||||
_isd.Table<_isc.UuidValue?> get table => PdfReading.t;
|
||||
}
|
||||
|
||||
class PdfReadingIncludeList extends _isd.IncludeList {
|
||||
PdfReadingIncludeList._({
|
||||
_isd.WhereExpressionBuilder<PdfReadingTable>? where,
|
||||
super.limit,
|
||||
super.offset,
|
||||
super.orderBy,
|
||||
super.orderByList,
|
||||
super.include,
|
||||
}) {
|
||||
super.where = where?.call(PdfReading.t);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, _isd.Include?> get includes => include?.includes ?? {};
|
||||
|
||||
@override
|
||||
_isd.Table<_isc.UuidValue?> get table => PdfReading.t;
|
||||
}
|
||||
|
||||
class PdfReadingRepository {
|
||||
const PdfReadingRepository._();
|
||||
|
||||
final attachRow = const PdfReadingAttachRowRepository._();
|
||||
|
||||
/// Returns a list of [PdfReading]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<PdfReading>> find(
|
||||
_isd.DatabaseSession session, {
|
||||
_isd.WhereExpressionBuilder<PdfReadingTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_isd.OrderByBuilder<PdfReadingTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfReadingTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
PdfReadingInclude? include,
|
||||
_isd.LockMode? lockMode,
|
||||
_isd.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.find<PdfReading>(
|
||||
where: where?.call(PdfReading.t),
|
||||
orderBy: orderBy?.call(PdfReading.t),
|
||||
orderByList: orderByList?.call(PdfReading.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the first matching [PdfReading] 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<PdfReading?> findFirstRow(
|
||||
_isd.DatabaseSession session, {
|
||||
_isd.WhereExpressionBuilder<PdfReadingTable>? where,
|
||||
int? offset,
|
||||
_isd.OrderByBuilder<PdfReadingTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfReadingTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
PdfReadingInclude? include,
|
||||
_isd.LockMode? lockMode,
|
||||
_isd.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findFirstRow<PdfReading>(
|
||||
where: where?.call(PdfReading.t),
|
||||
orderBy: orderBy?.call(PdfReading.t),
|
||||
orderByList: orderByList?.call(PdfReading.t),
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Finds a single [PdfReading] by its [id] or null if no such row exists.
|
||||
Future<PdfReading?> findById(
|
||||
_isd.DatabaseSession session,
|
||||
_isc.UuidValue id, {
|
||||
_isd.Transaction? transaction,
|
||||
PdfReadingInclude? include,
|
||||
_isd.LockMode? lockMode,
|
||||
_isd.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findById<PdfReading>(
|
||||
id,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts all [PdfReading]s in the list and returns the inserted rows.
|
||||
///
|
||||
/// The returned [PdfReading]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<PdfReading>> insert(
|
||||
_isd.DatabaseSession session,
|
||||
List<PdfReading> rows, {
|
||||
_isd.Transaction? transaction,
|
||||
bool ignoreConflicts = false,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.insert<PdfReading>(
|
||||
rows,
|
||||
transaction: transaction,
|
||||
ignoreConflicts: ignoreConflicts,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts a single [PdfReading] and returns the inserted row.
|
||||
///
|
||||
/// The returned [PdfReading] will have its `id` field set.
|
||||
Future<PdfReading> insertRow(
|
||||
_isd.DatabaseSession session,
|
||||
PdfReading row, {
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.insertRow<PdfReading>(
|
||||
row,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts all [PdfReading]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 [PdfReading]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<PdfReading>> upsert(
|
||||
_isd.DatabaseSession session,
|
||||
List<PdfReading> rows, {
|
||||
required _isd.ColumnSelections<PdfReadingTable> conflictColumns,
|
||||
_isd.ColumnSelections<PdfReadingTable>? updateColumns,
|
||||
_isd.WhereExpressionBuilder<PdfReadingTable>? updateWhere,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.upsert<PdfReading>(
|
||||
rows,
|
||||
conflictColumns: conflictColumns(PdfReading.t),
|
||||
updateColumns: updateColumns?.call(PdfReading.t),
|
||||
updateWhere: updateWhere?.call(PdfReading.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts a single [PdfReading] 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 [PdfReading] will have its `id` field set.
|
||||
Future<PdfReading?> upsertRow(
|
||||
_isd.DatabaseSession session,
|
||||
PdfReading row, {
|
||||
required _isd.ColumnSelections<PdfReadingTable> conflictColumns,
|
||||
_isd.ColumnSelections<PdfReadingTable>? updateColumns,
|
||||
_isd.WhereExpressionBuilder<PdfReadingTable>? updateWhere,
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.upsertRow<PdfReading>(
|
||||
row,
|
||||
conflictColumns: conflictColumns(PdfReading.t),
|
||||
updateColumns: updateColumns?.call(PdfReading.t),
|
||||
updateWhere: updateWhere?.call(PdfReading.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [PdfReading]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<PdfReading>> update(
|
||||
_isd.DatabaseSession session,
|
||||
List<PdfReading> rows, {
|
||||
_isd.ColumnSelections<PdfReadingTable>? columns,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.update<PdfReading>(
|
||||
rows,
|
||||
columns: columns?.call(PdfReading.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [PdfReading]. 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<PdfReading> updateRow(
|
||||
_isd.DatabaseSession session,
|
||||
PdfReading row, {
|
||||
_isd.ColumnSelections<PdfReadingTable>? columns,
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateRow<PdfReading>(
|
||||
row,
|
||||
columns: columns?.call(PdfReading.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [PdfReading] by its [id] with the specified [columnValues].
|
||||
/// Returns the updated row or null if no row with the given id exists.
|
||||
Future<PdfReading?> updateById(
|
||||
_isd.DatabaseSession session,
|
||||
_isc.UuidValue id, {
|
||||
required _isd.ColumnValueListBuilder<PdfReadingUpdateTable> columnValues,
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateById<PdfReading>(
|
||||
id,
|
||||
columnValues: columnValues(PdfReading.t.updateTable),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [PdfReading]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<PdfReading>> updateWhere(
|
||||
_isd.DatabaseSession session, {
|
||||
required _isd.ColumnValueListBuilder<PdfReadingUpdateTable> columnValues,
|
||||
required _isd.WhereExpressionBuilder<PdfReadingTable> where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_isd.OrderByBuilder<PdfReadingTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfReadingTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.updateWhere<PdfReading>(
|
||||
columnValues: columnValues(PdfReading.t.updateTable),
|
||||
where: where(PdfReading.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(PdfReading.t),
|
||||
orderByList: orderByList?.call(PdfReading.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes all [PdfReading]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<PdfReading>> delete(
|
||||
_isd.DatabaseSession session,
|
||||
List<PdfReading> rows, {
|
||||
_isd.OrderByBuilder<PdfReadingTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfReadingTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.delete<PdfReading>(
|
||||
rows,
|
||||
orderBy: orderBy?.call(PdfReading.t),
|
||||
orderByList: orderByList?.call(PdfReading.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes a single [PdfReading].
|
||||
Future<PdfReading> deleteRow(
|
||||
_isd.DatabaseSession session,
|
||||
PdfReading row, {
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.deleteRow<PdfReading>(
|
||||
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<PdfReading>> deleteWhere(
|
||||
_isd.DatabaseSession session, {
|
||||
required _isd.WhereExpressionBuilder<PdfReadingTable> where,
|
||||
_isd.OrderByBuilder<PdfReadingTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfReadingTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.deleteWhere<PdfReading>(
|
||||
where: where(PdfReading.t),
|
||||
orderBy: orderBy?.call(PdfReading.t),
|
||||
orderByList: orderByList?.call(PdfReading.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Counts the number of rows matching the [where] expression. If omitted,
|
||||
/// will return the count of all rows in the table.
|
||||
Future<int> count(
|
||||
_isd.DatabaseSession session, {
|
||||
_isd.WhereExpressionBuilder<PdfReadingTable>? where,
|
||||
int? limit,
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.count<PdfReading>(
|
||||
where: where?.call(PdfReading.t),
|
||||
limit: limit,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Acquires row-level locks on [PdfReading] rows matching the [where] expression.
|
||||
Future<void> lockRows(
|
||||
_isd.DatabaseSession session, {
|
||||
required _isd.WhereExpressionBuilder<PdfReadingTable> where,
|
||||
required _isd.LockMode lockMode,
|
||||
required _isd.Transaction transaction,
|
||||
_isd.LockBehavior lockBehavior = _isd.LockBehavior.wait,
|
||||
}) async {
|
||||
return session.db.lockRows<PdfReading>(
|
||||
where: where(PdfReading.t),
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PdfReadingAttachRowRepository {
|
||||
const PdfReadingAttachRowRepository._();
|
||||
|
||||
/// Creates a relation between the given [PdfReading] and [PdfSource]
|
||||
/// by setting the [PdfReading]'s foreign key `pdfSourceId` to refer to the [PdfSource].
|
||||
Future<void> pdfSource(
|
||||
_isd.DatabaseSession session,
|
||||
PdfReading pdfReading,
|
||||
_ijdmmu1w.PdfSource pdfSource, {
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
if (pdfReading.id == null) {
|
||||
throw ArgumentError.notNull('pdfReading.id');
|
||||
}
|
||||
if (pdfSource.id == null) {
|
||||
throw ArgumentError.notNull('pdfSource.id');
|
||||
}
|
||||
|
||||
var $pdfReading = pdfReading.copyWith(pdfSourceId: pdfSource.id);
|
||||
await session.db.updateRow<PdfReading>(
|
||||
$pdfReading,
|
||||
columns: [PdfReading.t.pdfSourceId],
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
790
halkyon_learn_client/lib/src/protocol/pdf_source/pdf_source.dart
Normal file
790
halkyon_learn_client/lib/src/protocol/pdf_source/pdf_source.dart
Normal file
|
|
@ -0,0 +1,790 @@
|
|||
/* 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_client/src/protocol/protocol.dart' as _itx5j3f5;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import 'package:serverpod_database/serverpod_database.dart' as _isd;
|
||||
import '../studyset/studyset.dart' as _ie5k1jc2;
|
||||
|
||||
/// A PDF in a studyset, to read and learn from: its cards and notes can be tied
|
||||
/// to its pages. Synced; its space owns it.
|
||||
///
|
||||
/// Its content (title, the name the file came with, the file, its page count
|
||||
/// once known, a reading deadline) lives in the payload, last writer wins, as a
|
||||
/// learning path's: rarely edited on two devices at once. The file itself is
|
||||
/// an asset (ADR 0004), named in the payload by the asset row's id.
|
||||
abstract class PdfSource
|
||||
implements _isd.TableRow<_isc.UuidValue?>, _isc.ProtocolSerialization {
|
||||
PdfSource._({
|
||||
this.id,
|
||||
this.spaceId,
|
||||
required this.studysetId,
|
||||
this.studyset,
|
||||
this.keyId,
|
||||
required this.payload,
|
||||
this.nonce,
|
||||
});
|
||||
|
||||
factory PdfSource({
|
||||
_isc.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _isc.UuidValue studysetId,
|
||||
_ie5k1jc2.Studyset? studyset,
|
||||
String? keyId,
|
||||
required _idt.ByteData payload,
|
||||
_idt.ByteData? nonce,
|
||||
}) = _PdfSourceImpl;
|
||||
|
||||
factory PdfSource.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return PdfSource(
|
||||
id: jsonSerialization['id'] == null
|
||||
? null
|
||||
: _isc.UuidValueJsonExtension.fromJson(jsonSerialization['id']),
|
||||
spaceId: jsonSerialization['spaceId'] as int?,
|
||||
studysetId: _isc.UuidValueJsonExtension.fromJson(
|
||||
jsonSerialization['studysetId'],
|
||||
),
|
||||
studyset: jsonSerialization['studyset'] == null
|
||||
? null
|
||||
: _itx5j3f5.Protocol().deserialize<_ie5k1jc2.Studyset>(
|
||||
jsonSerialization['studyset'],
|
||||
),
|
||||
keyId: jsonSerialization['keyId'] as String?,
|
||||
payload: _isc.ByteDataJsonExtension.fromJson(
|
||||
jsonSerialization['payload'],
|
||||
),
|
||||
nonce: jsonSerialization['nonce'] == null
|
||||
? null
|
||||
: _isc.ByteDataJsonExtension.fromJson(jsonSerialization['nonce']),
|
||||
);
|
||||
}
|
||||
|
||||
static final t = PdfSourceTable();
|
||||
|
||||
static const db = PdfSourceRepository._();
|
||||
|
||||
@override
|
||||
_isc.UuidValue? id;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
int? spaceId;
|
||||
|
||||
_isc.UuidValue studysetId;
|
||||
|
||||
/// The studyset the PDF belongs to; the PDF goes with it.
|
||||
_ie5k1jc2.Studyset? studyset;
|
||||
|
||||
/// The encryption key's id; always null (ADR 0002, rule 6).
|
||||
String? keyId;
|
||||
|
||||
/// The content as UTF-8 JSON: {"schemaVersion", "title", "fileName", "asset",
|
||||
/// "pageCount", "deadline"}; the app's pdf_source_payload.dart describes each
|
||||
/// schema.
|
||||
_idt.ByteData payload;
|
||||
|
||||
/// The encryption nonce; always null, like keyId.
|
||||
_idt.ByteData? nonce;
|
||||
|
||||
@override
|
||||
_isd.Table<_isc.UuidValue?> get table => t;
|
||||
|
||||
/// Returns a shallow copy of this [PdfSource]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
PdfSource copyWith({
|
||||
_isc.UuidValue? id,
|
||||
int? spaceId,
|
||||
_isc.UuidValue? studysetId,
|
||||
_ie5k1jc2.Studyset? studyset,
|
||||
String? keyId,
|
||||
_idt.ByteData? payload,
|
||||
_idt.ByteData? nonce,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'PdfSource',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'studysetId': studysetId.toJson(),
|
||||
if (studyset != null) 'studyset': studyset?.toJson(),
|
||||
if (keyId != null) 'keyId': keyId,
|
||||
'payload': payload.toJson(),
|
||||
if (nonce != null) 'nonce': nonce?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'PdfSource',
|
||||
if (id != null) 'id': id?.toJson(),
|
||||
if (spaceId != null) 'spaceId': spaceId,
|
||||
'studysetId': studysetId.toJson(),
|
||||
if (studyset != null) 'studyset': studyset?.toJsonForProtocol(),
|
||||
if (keyId != null) 'keyId': keyId,
|
||||
'payload': payload.toJson(),
|
||||
if (nonce != null) 'nonce': nonce?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
static PdfSourceInclude include({_ie5k1jc2.StudysetInclude? studyset}) {
|
||||
return PdfSourceInclude._(studyset: studyset);
|
||||
}
|
||||
|
||||
static PdfSourceIncludeList includeList({
|
||||
_isd.WhereExpressionBuilder<PdfSourceTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_isd.OrderByBuilder<PdfSourceTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfSourceTable>? orderByList,
|
||||
PdfSourceInclude? include,
|
||||
}) {
|
||||
return PdfSourceIncludeList._(
|
||||
where: where,
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(PdfSource.t),
|
||||
orderByList: orderByList?.call(PdfSource.t),
|
||||
include: include,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _Undefined {}
|
||||
|
||||
class _PdfSourceImpl extends PdfSource {
|
||||
_PdfSourceImpl({
|
||||
_isc.UuidValue? id,
|
||||
int? spaceId,
|
||||
required _isc.UuidValue studysetId,
|
||||
_ie5k1jc2.Studyset? studyset,
|
||||
String? keyId,
|
||||
required _idt.ByteData payload,
|
||||
_idt.ByteData? nonce,
|
||||
}) : super._(
|
||||
id: id,
|
||||
spaceId: spaceId,
|
||||
studysetId: studysetId,
|
||||
studyset: studyset,
|
||||
keyId: keyId,
|
||||
payload: payload,
|
||||
nonce: nonce,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [PdfSource]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
PdfSource copyWith({
|
||||
Object? id = _Undefined,
|
||||
Object? spaceId = _Undefined,
|
||||
_isc.UuidValue? studysetId,
|
||||
Object? studyset = _Undefined,
|
||||
Object? keyId = _Undefined,
|
||||
_idt.ByteData? payload,
|
||||
Object? nonce = _Undefined,
|
||||
}) {
|
||||
return PdfSource(
|
||||
id: id is _isc.UuidValue? ? id : this.id,
|
||||
spaceId: spaceId is int? ? spaceId : this.spaceId,
|
||||
studysetId: studysetId ?? this.studysetId,
|
||||
studyset: studyset is _ie5k1jc2.Studyset?
|
||||
? studyset
|
||||
: this.studyset?.copyWith(),
|
||||
keyId: keyId is String? ? keyId : this.keyId,
|
||||
payload: payload ?? this.payload.clone(),
|
||||
nonce: nonce is _idt.ByteData? ? nonce : this.nonce?.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PdfSourceUpdateTable extends _isd.UpdateTable<PdfSourceTable> {
|
||||
PdfSourceUpdateTable(super.table);
|
||||
|
||||
_isd.ColumnValue<int, int> spaceId(int? value) => _isd.ColumnValue(
|
||||
table.spaceId,
|
||||
value,
|
||||
);
|
||||
|
||||
_isd.ColumnValue<_isc.UuidValue, _isc.UuidValue> studysetId(
|
||||
_isc.UuidValue value,
|
||||
) => _isd.ColumnValue(
|
||||
table.studysetId,
|
||||
value,
|
||||
);
|
||||
|
||||
_isd.ColumnValue<String, String> keyId(String? value) => _isd.ColumnValue(
|
||||
table.keyId,
|
||||
value,
|
||||
);
|
||||
|
||||
_isd.ColumnValue<_idt.ByteData, _idt.ByteData> payload(_idt.ByteData value) =>
|
||||
_isd.ColumnValue(
|
||||
table.payload,
|
||||
value,
|
||||
);
|
||||
|
||||
_isd.ColumnValue<_idt.ByteData, _idt.ByteData> nonce(_idt.ByteData? value) =>
|
||||
_isd.ColumnValue(
|
||||
table.nonce,
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
class PdfSourceTable extends _isd.Table<_isc.UuidValue?> {
|
||||
PdfSourceTable({super.tableRelation}) : super(tableName: 'pdf_source') {
|
||||
updateTable = PdfSourceUpdateTable(this);
|
||||
spaceId = _isd.ColumnInt(
|
||||
'spaceId',
|
||||
this,
|
||||
);
|
||||
studysetId = _isd.ColumnUuid(
|
||||
'studysetId',
|
||||
this,
|
||||
);
|
||||
keyId = _isd.ColumnString(
|
||||
'keyId',
|
||||
this,
|
||||
);
|
||||
payload = _isd.ColumnByteData(
|
||||
'payload',
|
||||
this,
|
||||
);
|
||||
nonce = _isd.ColumnByteData(
|
||||
'nonce',
|
||||
this,
|
||||
);
|
||||
}
|
||||
|
||||
late final PdfSourceUpdateTable updateTable;
|
||||
|
||||
/// The space owning this row. Maintained by the sync engine.
|
||||
late final _isd.ColumnInt spaceId;
|
||||
|
||||
late final _isd.ColumnUuid studysetId;
|
||||
|
||||
/// The studyset the PDF belongs to; the PDF goes with it.
|
||||
_ie5k1jc2.StudysetTable? _studyset;
|
||||
|
||||
/// The encryption key's id; always null (ADR 0002, rule 6).
|
||||
late final _isd.ColumnString keyId;
|
||||
|
||||
/// The content as UTF-8 JSON: {"schemaVersion", "title", "fileName", "asset",
|
||||
/// "pageCount", "deadline"}; the app's pdf_source_payload.dart describes each
|
||||
/// schema.
|
||||
late final _isd.ColumnByteData payload;
|
||||
|
||||
/// The encryption nonce; always null, like keyId.
|
||||
late final _isd.ColumnByteData nonce;
|
||||
|
||||
_ie5k1jc2.StudysetTable get studyset {
|
||||
if (_studyset != null) return _studyset!;
|
||||
_studyset = _isd.createRelationTable(
|
||||
relationFieldName: 'studyset',
|
||||
field: PdfSource.t.studysetId,
|
||||
foreignField: _ie5k1jc2.Studyset.t.id,
|
||||
tableRelation: tableRelation,
|
||||
createTable: (foreignTableRelation) =>
|
||||
_ie5k1jc2.StudysetTable(tableRelation: foreignTableRelation),
|
||||
);
|
||||
return _studyset!;
|
||||
}
|
||||
|
||||
@override
|
||||
List<_isd.Column> get columns => [
|
||||
id,
|
||||
spaceId,
|
||||
studysetId,
|
||||
keyId,
|
||||
payload,
|
||||
nonce,
|
||||
];
|
||||
|
||||
@override
|
||||
_isd.Table? getRelationTable(String relationField) {
|
||||
if (relationField == 'studyset') {
|
||||
return studyset;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class PdfSourceInclude extends _isd.IncludeObject {
|
||||
PdfSourceInclude._({_ie5k1jc2.StudysetInclude? studyset}) {
|
||||
_studyset = studyset;
|
||||
}
|
||||
|
||||
_ie5k1jc2.StudysetInclude? _studyset;
|
||||
|
||||
@override
|
||||
Map<String, _isd.Include?> get includes => {'studyset': _studyset};
|
||||
|
||||
@override
|
||||
_isd.Table<_isc.UuidValue?> get table => PdfSource.t;
|
||||
}
|
||||
|
||||
class PdfSourceIncludeList extends _isd.IncludeList {
|
||||
PdfSourceIncludeList._({
|
||||
_isd.WhereExpressionBuilder<PdfSourceTable>? where,
|
||||
super.limit,
|
||||
super.offset,
|
||||
super.orderBy,
|
||||
super.orderByList,
|
||||
super.include,
|
||||
}) {
|
||||
super.where = where?.call(PdfSource.t);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, _isd.Include?> get includes => include?.includes ?? {};
|
||||
|
||||
@override
|
||||
_isd.Table<_isc.UuidValue?> get table => PdfSource.t;
|
||||
}
|
||||
|
||||
class PdfSourceRepository {
|
||||
const PdfSourceRepository._();
|
||||
|
||||
final attachRow = const PdfSourceAttachRowRepository._();
|
||||
|
||||
/// Returns a list of [PdfSource]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<PdfSource>> find(
|
||||
_isd.DatabaseSession session, {
|
||||
_isd.WhereExpressionBuilder<PdfSourceTable>? where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_isd.OrderByBuilder<PdfSourceTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfSourceTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
PdfSourceInclude? include,
|
||||
_isd.LockMode? lockMode,
|
||||
_isd.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.find<PdfSource>(
|
||||
where: where?.call(PdfSource.t),
|
||||
orderBy: orderBy?.call(PdfSource.t),
|
||||
orderByList: orderByList?.call(PdfSource.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the first matching [PdfSource] 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<PdfSource?> findFirstRow(
|
||||
_isd.DatabaseSession session, {
|
||||
_isd.WhereExpressionBuilder<PdfSourceTable>? where,
|
||||
int? offset,
|
||||
_isd.OrderByBuilder<PdfSourceTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfSourceTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
PdfSourceInclude? include,
|
||||
_isd.LockMode? lockMode,
|
||||
_isd.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findFirstRow<PdfSource>(
|
||||
where: where?.call(PdfSource.t),
|
||||
orderBy: orderBy?.call(PdfSource.t),
|
||||
orderByList: orderByList?.call(PdfSource.t),
|
||||
offset: offset,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Finds a single [PdfSource] by its [id] or null if no such row exists.
|
||||
Future<PdfSource?> findById(
|
||||
_isd.DatabaseSession session,
|
||||
_isc.UuidValue id, {
|
||||
_isd.Transaction? transaction,
|
||||
PdfSourceInclude? include,
|
||||
_isd.LockMode? lockMode,
|
||||
_isd.LockBehavior? lockBehavior,
|
||||
}) async {
|
||||
return session.db.findById<PdfSource>(
|
||||
id,
|
||||
transaction: transaction,
|
||||
include: include,
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts all [PdfSource]s in the list and returns the inserted rows.
|
||||
///
|
||||
/// The returned [PdfSource]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<PdfSource>> insert(
|
||||
_isd.DatabaseSession session,
|
||||
List<PdfSource> rows, {
|
||||
_isd.Transaction? transaction,
|
||||
bool ignoreConflicts = false,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.insert<PdfSource>(
|
||||
rows,
|
||||
transaction: transaction,
|
||||
ignoreConflicts: ignoreConflicts,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Inserts a single [PdfSource] and returns the inserted row.
|
||||
///
|
||||
/// The returned [PdfSource] will have its `id` field set.
|
||||
Future<PdfSource> insertRow(
|
||||
_isd.DatabaseSession session,
|
||||
PdfSource row, {
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.insertRow<PdfSource>(
|
||||
row,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts all [PdfSource]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 [PdfSource]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<PdfSource>> upsert(
|
||||
_isd.DatabaseSession session,
|
||||
List<PdfSource> rows, {
|
||||
required _isd.ColumnSelections<PdfSourceTable> conflictColumns,
|
||||
_isd.ColumnSelections<PdfSourceTable>? updateColumns,
|
||||
_isd.WhereExpressionBuilder<PdfSourceTable>? updateWhere,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.upsert<PdfSource>(
|
||||
rows,
|
||||
conflictColumns: conflictColumns(PdfSource.t),
|
||||
updateColumns: updateColumns?.call(PdfSource.t),
|
||||
updateWhere: updateWhere?.call(PdfSource.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Upserts a single [PdfSource] 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 [PdfSource] will have its `id` field set.
|
||||
Future<PdfSource?> upsertRow(
|
||||
_isd.DatabaseSession session,
|
||||
PdfSource row, {
|
||||
required _isd.ColumnSelections<PdfSourceTable> conflictColumns,
|
||||
_isd.ColumnSelections<PdfSourceTable>? updateColumns,
|
||||
_isd.WhereExpressionBuilder<PdfSourceTable>? updateWhere,
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.upsertRow<PdfSource>(
|
||||
row,
|
||||
conflictColumns: conflictColumns(PdfSource.t),
|
||||
updateColumns: updateColumns?.call(PdfSource.t),
|
||||
updateWhere: updateWhere?.call(PdfSource.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [PdfSource]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<PdfSource>> update(
|
||||
_isd.DatabaseSession session,
|
||||
List<PdfSource> rows, {
|
||||
_isd.ColumnSelections<PdfSourceTable>? columns,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.update<PdfSource>(
|
||||
rows,
|
||||
columns: columns?.call(PdfSource.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [PdfSource]. 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<PdfSource> updateRow(
|
||||
_isd.DatabaseSession session,
|
||||
PdfSource row, {
|
||||
_isd.ColumnSelections<PdfSourceTable>? columns,
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateRow<PdfSource>(
|
||||
row,
|
||||
columns: columns?.call(PdfSource.t),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates a single [PdfSource] by its [id] with the specified [columnValues].
|
||||
/// Returns the updated row or null if no row with the given id exists.
|
||||
Future<PdfSource?> updateById(
|
||||
_isd.DatabaseSession session,
|
||||
_isc.UuidValue id, {
|
||||
required _isd.ColumnValueListBuilder<PdfSourceUpdateTable> columnValues,
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.updateById<PdfSource>(
|
||||
id,
|
||||
columnValues: columnValues(PdfSource.t.updateTable),
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Updates all [PdfSource]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<PdfSource>> updateWhere(
|
||||
_isd.DatabaseSession session, {
|
||||
required _isd.ColumnValueListBuilder<PdfSourceUpdateTable> columnValues,
|
||||
required _isd.WhereExpressionBuilder<PdfSourceTable> where,
|
||||
int? limit,
|
||||
int? offset,
|
||||
_isd.OrderByBuilder<PdfSourceTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfSourceTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.updateWhere<PdfSource>(
|
||||
columnValues: columnValues(PdfSource.t.updateTable),
|
||||
where: where(PdfSource.t),
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
orderBy: orderBy?.call(PdfSource.t),
|
||||
orderByList: orderByList?.call(PdfSource.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes all [PdfSource]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<PdfSource>> delete(
|
||||
_isd.DatabaseSession session,
|
||||
List<PdfSource> rows, {
|
||||
_isd.OrderByBuilder<PdfSourceTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfSourceTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.delete<PdfSource>(
|
||||
rows,
|
||||
orderBy: orderBy?.call(PdfSource.t),
|
||||
orderByList: orderByList?.call(PdfSource.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Deletes a single [PdfSource].
|
||||
Future<PdfSource> deleteRow(
|
||||
_isd.DatabaseSession session,
|
||||
PdfSource row, {
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.deleteRow<PdfSource>(
|
||||
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<PdfSource>> deleteWhere(
|
||||
_isd.DatabaseSession session, {
|
||||
required _isd.WhereExpressionBuilder<PdfSourceTable> where,
|
||||
_isd.OrderByBuilder<PdfSourceTable>? orderBy,
|
||||
_isd.OrderByListBuilder<PdfSourceTable>? orderByList,
|
||||
_isd.Transaction? transaction,
|
||||
bool noReturn = false,
|
||||
}) async {
|
||||
return session.db.deleteWhere<PdfSource>(
|
||||
where: where(PdfSource.t),
|
||||
orderBy: orderBy?.call(PdfSource.t),
|
||||
orderByList: orderByList?.call(PdfSource.t),
|
||||
transaction: transaction,
|
||||
noReturn: noReturn,
|
||||
);
|
||||
}
|
||||
|
||||
/// Counts the number of rows matching the [where] expression. If omitted,
|
||||
/// will return the count of all rows in the table.
|
||||
Future<int> count(
|
||||
_isd.DatabaseSession session, {
|
||||
_isd.WhereExpressionBuilder<PdfSourceTable>? where,
|
||||
int? limit,
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
return session.db.count<PdfSource>(
|
||||
where: where?.call(PdfSource.t),
|
||||
limit: limit,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
|
||||
/// Acquires row-level locks on [PdfSource] rows matching the [where] expression.
|
||||
Future<void> lockRows(
|
||||
_isd.DatabaseSession session, {
|
||||
required _isd.WhereExpressionBuilder<PdfSourceTable> where,
|
||||
required _isd.LockMode lockMode,
|
||||
required _isd.Transaction transaction,
|
||||
_isd.LockBehavior lockBehavior = _isd.LockBehavior.wait,
|
||||
}) async {
|
||||
return session.db.lockRows<PdfSource>(
|
||||
where: where(PdfSource.t),
|
||||
lockMode: lockMode,
|
||||
lockBehavior: lockBehavior,
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PdfSourceAttachRowRepository {
|
||||
const PdfSourceAttachRowRepository._();
|
||||
|
||||
/// Creates a relation between the given [PdfSource] and [Studyset]
|
||||
/// by setting the [PdfSource]'s foreign key `studysetId` to refer to the [Studyset].
|
||||
Future<void> studyset(
|
||||
_isd.DatabaseSession session,
|
||||
PdfSource pdfSource,
|
||||
_ie5k1jc2.Studyset studyset, {
|
||||
_isd.Transaction? transaction,
|
||||
}) async {
|
||||
if (pdfSource.id == null) {
|
||||
throw ArgumentError.notNull('pdfSource.id');
|
||||
}
|
||||
if (studyset.id == null) {
|
||||
throw ArgumentError.notNull('studyset.id');
|
||||
}
|
||||
|
||||
var $pdfSource = pdfSource.copyWith(studysetId: studyset.id);
|
||||
await session.db.updateRow<PdfSource>(
|
||||
$pdfSource,
|
||||
columns: [PdfSource.t.studysetId],
|
||||
transaction: transaction,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -38,6 +38,8 @@ import 'learning_path/learning_path_step.dart' as _irnpk9dc;
|
|||
import 'learning_path/learning_path_step_revision.dart' as _i59qfu1l;
|
||||
import 'note/note.dart' as _i9njjhyv;
|
||||
import 'note/note_revision.dart' as _i6j5dng4;
|
||||
import 'pdf_source/pdf_reading.dart' as _i4l20c7i;
|
||||
import 'pdf_source/pdf_source.dart' as _iz838ro9;
|
||||
import 'review/review_log.dart' as _irzjbdqz;
|
||||
import 'settings/person_settings.dart' as _irnhx5e5;
|
||||
import 'studyset/studyset.dart' as _ikbclmae;
|
||||
|
|
@ -62,6 +64,8 @@ export 'learning_path/learning_path_step.dart';
|
|||
export 'learning_path/learning_path_step_revision.dart';
|
||||
export 'note/note.dart';
|
||||
export 'note/note_revision.dart';
|
||||
export 'pdf_source/pdf_reading.dart';
|
||||
export 'pdf_source/pdf_source.dart';
|
||||
export 'review/review_log.dart';
|
||||
export 'settings/person_settings.dart';
|
||||
export 'studyset/studyset.dart';
|
||||
|
|
@ -1335,6 +1339,204 @@ class Protocol extends _isd.DatabaseSerializationManager {
|
|||
],
|
||||
managed: true,
|
||||
),
|
||||
_isd.TableDefinition(
|
||||
name: 'pdf_reading',
|
||||
dartName: 'PdfReading',
|
||||
schema: 'public',
|
||||
module: 'halkyon_learn',
|
||||
columns: [
|
||||
_isd.ColumnDefinition(
|
||||
name: 'id',
|
||||
columnType: _isd.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue?',
|
||||
columnDefault: 'random_v7',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'spaceId',
|
||||
columnType: _isd.ColumnType.bigint,
|
||||
isNullable: true,
|
||||
dartType: 'int?',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'pdfSourceId',
|
||||
columnType: _isd.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'readAt',
|
||||
columnType: _isd.ColumnType.timestampWithoutTimeZone,
|
||||
isNullable: false,
|
||||
dartType: 'DateTime',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'kind',
|
||||
columnType: _isd.ColumnType.text,
|
||||
isNullable: false,
|
||||
dartType: 'String',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'page',
|
||||
columnType: _isd.ColumnType.bigint,
|
||||
isNullable: false,
|
||||
dartType: 'int',
|
||||
),
|
||||
],
|
||||
foreignKeys: [
|
||||
_isd.ForeignKeyDefinition(
|
||||
constraintName: 'pdf_reading_fk_0',
|
||||
columns: ['spaceId'],
|
||||
referenceTable: 'offline_sync_spaces',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isd.ForeignKeyAction.noAction,
|
||||
onDelete: _isd.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
),
|
||||
_isd.ForeignKeyDefinition(
|
||||
constraintName: 'pdf_reading_fk_1',
|
||||
columns: ['pdfSourceId'],
|
||||
referenceTable: 'pdf_source',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isd.ForeignKeyAction.noAction,
|
||||
onDelete: _isd.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
deferrable: _isd.DeferrableConstraint.initiallyDeferred,
|
||||
),
|
||||
],
|
||||
indexes: [
|
||||
_isd.IndexDefinition(
|
||||
indexName: 'pdf_reading_space_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isd.IndexElementDefinition(
|
||||
type: _isd.IndexElementDefinitionType.column,
|
||||
definition: 'spaceId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
_isd.IndexDefinition(
|
||||
indexName: 'pdf_reading_source_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isd.IndexElementDefinition(
|
||||
type: _isd.IndexElementDefinitionType.column,
|
||||
definition: 'pdfSourceId',
|
||||
),
|
||||
_isd.IndexElementDefinition(
|
||||
type: _isd.IndexElementDefinitionType.column,
|
||||
definition: 'readAt',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
],
|
||||
managed: true,
|
||||
),
|
||||
_isd.TableDefinition(
|
||||
name: 'pdf_source',
|
||||
dartName: 'PdfSource',
|
||||
schema: 'public',
|
||||
module: 'halkyon_learn',
|
||||
columns: [
|
||||
_isd.ColumnDefinition(
|
||||
name: 'id',
|
||||
columnType: _isd.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue?',
|
||||
columnDefault: 'random_v7',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'spaceId',
|
||||
columnType: _isd.ColumnType.bigint,
|
||||
isNullable: true,
|
||||
dartType: 'int?',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'studysetId',
|
||||
columnType: _isd.ColumnType.uuid,
|
||||
isNullable: false,
|
||||
dartType: 'UuidValue',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'keyId',
|
||||
columnType: _isd.ColumnType.text,
|
||||
isNullable: true,
|
||||
dartType: 'String?',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'payload',
|
||||
columnType: _isd.ColumnType.bytea,
|
||||
isNullable: false,
|
||||
dartType: 'dart:typed_data:ByteData',
|
||||
),
|
||||
_isd.ColumnDefinition(
|
||||
name: 'nonce',
|
||||
columnType: _isd.ColumnType.bytea,
|
||||
isNullable: true,
|
||||
dartType: 'dart:typed_data:ByteData?',
|
||||
),
|
||||
],
|
||||
foreignKeys: [
|
||||
_isd.ForeignKeyDefinition(
|
||||
constraintName: 'pdf_source_fk_0',
|
||||
columns: ['spaceId'],
|
||||
referenceTable: 'offline_sync_spaces',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isd.ForeignKeyAction.noAction,
|
||||
onDelete: _isd.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
),
|
||||
_isd.ForeignKeyDefinition(
|
||||
constraintName: 'pdf_source_fk_1',
|
||||
columns: ['studysetId'],
|
||||
referenceTable: 'studyset',
|
||||
referenceTableSchema: 'public',
|
||||
referenceColumns: ['id'],
|
||||
onUpdate: _isd.ForeignKeyAction.noAction,
|
||||
onDelete: _isd.ForeignKeyAction.cascade,
|
||||
matchType: null,
|
||||
deferrable: _isd.DeferrableConstraint.initiallyDeferred,
|
||||
),
|
||||
],
|
||||
indexes: [
|
||||
_isd.IndexDefinition(
|
||||
indexName: 'pdf_source_space_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isd.IndexElementDefinition(
|
||||
type: _isd.IndexElementDefinitionType.column,
|
||||
definition: 'spaceId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
_isd.IndexDefinition(
|
||||
indexName: 'pdf_source_studyset_idx',
|
||||
tableSpace: null,
|
||||
elements: [
|
||||
_isd.IndexElementDefinition(
|
||||
type: _isd.IndexElementDefinitionType.column,
|
||||
definition: 'studysetId',
|
||||
),
|
||||
],
|
||||
type: 'btree',
|
||||
isUnique: false,
|
||||
isPrimary: false,
|
||||
),
|
||||
],
|
||||
managed: true,
|
||||
),
|
||||
_isd.TableDefinition(
|
||||
name: 'person_settings',
|
||||
dartName: 'PersonSettings',
|
||||
|
|
@ -1795,6 +1997,12 @@ class Protocol extends _isd.DatabaseSerializationManager {
|
|||
if (t == _i6j5dng4.NoteRevision) {
|
||||
return _i6j5dng4.NoteRevision.fromJson(data) as T;
|
||||
}
|
||||
if (t == _i4l20c7i.PdfReading) {
|
||||
return _i4l20c7i.PdfReading.fromJson(data) as T;
|
||||
}
|
||||
if (t == _iz838ro9.PdfSource) {
|
||||
return _iz838ro9.PdfSource.fromJson(data) as T;
|
||||
}
|
||||
if (t == _irzjbdqz.ReviewLog) {
|
||||
return _irzjbdqz.ReviewLog.fromJson(data) as T;
|
||||
}
|
||||
|
|
@ -1883,6 +2091,12 @@ class Protocol extends _isd.DatabaseSerializationManager {
|
|||
if (t == _isc.getType<_i6j5dng4.NoteRevision?>()) {
|
||||
return (data != null ? _i6j5dng4.NoteRevision.fromJson(data) : null) as T;
|
||||
}
|
||||
if (t == _isc.getType<_i4l20c7i.PdfReading?>()) {
|
||||
return (data != null ? _i4l20c7i.PdfReading.fromJson(data) : null) as T;
|
||||
}
|
||||
if (t == _isc.getType<_iz838ro9.PdfSource?>()) {
|
||||
return (data != null ? _iz838ro9.PdfSource.fromJson(data) : null) as T;
|
||||
}
|
||||
if (t == _isc.getType<_irzjbdqz.ReviewLog?>()) {
|
||||
return (data != null ? _irzjbdqz.ReviewLog.fromJson(data) : null) as T;
|
||||
}
|
||||
|
|
@ -1947,6 +2161,8 @@ class Protocol extends _isd.DatabaseSerializationManager {
|
|||
_i59qfu1l.LearningPathStepRevision => 'LearningPathStepRevision',
|
||||
_i9njjhyv.Note => 'Note',
|
||||
_i6j5dng4.NoteRevision => 'NoteRevision',
|
||||
_i4l20c7i.PdfReading => 'PdfReading',
|
||||
_iz838ro9.PdfSource => 'PdfSource',
|
||||
_irzjbdqz.ReviewLog => 'ReviewLog',
|
||||
_irnhx5e5.PersonSettings => 'PersonSettings',
|
||||
_ikbclmae.Studyset => 'Studyset',
|
||||
|
|
@ -2005,6 +2221,10 @@ class Protocol extends _isd.DatabaseSerializationManager {
|
|||
return 'Note';
|
||||
case _i6j5dng4.NoteRevision():
|
||||
return 'NoteRevision';
|
||||
case _i4l20c7i.PdfReading():
|
||||
return 'PdfReading';
|
||||
case _iz838ro9.PdfSource():
|
||||
return 'PdfSource';
|
||||
case _irzjbdqz.ReviewLog():
|
||||
return 'ReviewLog';
|
||||
case _irnhx5e5.PersonSettings():
|
||||
|
|
@ -2098,6 +2318,12 @@ class Protocol extends _isd.DatabaseSerializationManager {
|
|||
if (dataClassName == 'NoteRevision') {
|
||||
return deserialize<_i6j5dng4.NoteRevision>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'PdfReading') {
|
||||
return deserialize<_i4l20c7i.PdfReading>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'PdfSource') {
|
||||
return deserialize<_iz838ro9.PdfSource>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'ReviewLog') {
|
||||
return deserialize<_irzjbdqz.ReviewLog>(data['data']);
|
||||
}
|
||||
|
|
@ -2188,6 +2414,10 @@ class Protocol extends _isd.DatabaseSerializationManager {
|
|||
return _i9njjhyv.Note.t;
|
||||
case _i6j5dng4.NoteRevision:
|
||||
return _i6j5dng4.NoteRevision.t;
|
||||
case _i4l20c7i.PdfReading:
|
||||
return _i4l20c7i.PdfReading.t;
|
||||
case _iz838ro9.PdfSource:
|
||||
return _iz838ro9.PdfSource.t;
|
||||
case _irzjbdqz.ReviewLog:
|
||||
return _irzjbdqz.ReviewLog.t;
|
||||
case _irnhx5e5.PersonSettings:
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import 'learning_path/learning_path_step.dart' as _irnpk9dc;
|
|||
import 'learning_path/learning_path_step_revision.dart' as _i59qfu1l;
|
||||
import 'note/note.dart' as _i9njjhyv;
|
||||
import 'note/note_revision.dart' as _i6j5dng4;
|
||||
import 'pdf_source/pdf_reading.dart' as _i4l20c7i;
|
||||
import 'pdf_source/pdf_source.dart' as _iz838ro9;
|
||||
import 'review/review_log.dart' as _irzjbdqz;
|
||||
import 'settings/person_settings.dart' as _irnhx5e5;
|
||||
import 'studyset/studyset.dart' as _ikbclmae;
|
||||
|
|
@ -44,6 +46,8 @@ final List<_isd.Table> syncTables = [
|
|||
_i9njjhyv.Note.t,
|
||||
_i6j5dng4.NoteRevision.t,
|
||||
_itkfn57x.NoteTag.t,
|
||||
_i4l20c7i.PdfReading.t,
|
||||
_iz838ro9.PdfSource.t,
|
||||
_irnhx5e5.PersonSettings.t,
|
||||
_irzjbdqz.ReviewLog.t,
|
||||
_ikbclmae.Studyset.t,
|
||||
|
|
|
|||
Loading…
Reference in a new issue