11import '../connection/connection.dart' ;
22import '../database/connection_user.dart' ;
33import '../database/data_class.dart' ;
4+ import '../database/selectable.dart' ;
5+ import 'expressions/aggregate.dart' ;
6+ import 'expressions/expression.dart' ;
7+ import 'schema/result_set.dart' ;
48import 'schema/table.dart' ;
59import 'statements/insert.dart' ;
10+ import 'statements/select.dart' ;
11+
12+ /// Easily-accessible methods to compose common operations or statements on
13+ /// tables or views.
14+ extension type TableOrViewStatements <
15+ Row extends Object ,
16+ RS extends ResultSet <Row , RS >
17+ >._((RS , DatabaseConnectionUser ) _resultSetWithDatabase) {
18+ /// Selects all rows that are in this table.
19+ ///
20+ /// The returned [Selectable] can be run once as a future with [Selectable.get]
21+ /// or as an auto-updating stream with [Selectable.watch] .
22+ Selectable <Row > all () {
23+ return select ();
24+ }
25+
26+ /// Counts the rows in this table.
27+ ///
28+ /// The optional [where] clause can be used to only count rows matching the
29+ /// condition, similar to [SimpleSelectStatement.where] .
30+ ///
31+ /// The returned [Selectable] can be run once with [Selectable.getSingle] to
32+ /// get the count once, or be watched as a stream with [Selectable.watchSingle] .
33+ Selectable <int > count ({Expression <bool > Function (RS row)? where}) {
34+ final count = countAll ();
35+ final stmt = selectOnly ()..addColumns ([count]);
36+ if (where != null ) {
37+ stmt.where (where (_resultSetWithDatabase.$1));
38+ }
39+
40+ return stmt.map ((row) => row.read (count)! );
41+ }
42+
43+ /// Composes a `SELECT` statement on the captured table or view.
44+ ///
45+ /// This is equivalent to calling [DatabaseConnectionUser.select] .
46+ SingleTableSelectStatement <Row , RS > select ({bool distinct = false }) {
47+ final (rs, db) = _resultSetWithDatabase;
48+ return db.select (rs, distinct: distinct);
49+ }
50+
51+ /// Composes a `SELECT` statement only selecting a subset of columns.
52+ ///
53+ /// This is equivalent to calling [DatabaseConnectionUser.selectOnly] .
54+ SelectStatement selectOnly ({bool distinct = false }) {
55+ final (rs, db) = _resultSetWithDatabase;
56+ return db.selectOnly (rs, distinct: distinct);
57+ }
58+ }
659
760/// Easily-accessible methods to compose common operations or statements on
861/// tables.
9- extension TableStatements <
62+ extension type TableStatements <
1063 Row extends Object ,
1164 RS extends GeneratedTable <Row , RS >
12- >
13- on GeneratedTable <Row , RS > {
65+ >._( TableOrViewStatements < Row , RS > _super)
66+ implements TableOrViewStatements <Row , RS > {
1467 /// Creates an insert statment to be used to compose an insert on the table.
15- ///
16- /// To later run the statement, first call
17- /// [InsertStatementWithoutDatabase.onDatabase] followed by methods like
18- /// [InsertStatementWithDatabase.insert] .
19- InsertStatement <Row , RS , Null > insert () => InsertStatement (null , this );
68+ InsertStatement <Row , RS > insert () {
69+ final (rs, db) = _resultSetWithDatabase;
70+ return InsertStatement (db, rs);
71+ }
2072
2173 /// Inserts one row into this table.
2274 ///
23- /// This is equivalent to calling [InsertStatementWithDatabase .insert] - see
24- /// that method for more information.
75+ /// This is equivalent to calling [InsertStatement .insert] , see that method
76+ /// for more information.
2577 Future <int > insertOne (
2678 Insertable <Row > row, {
27- required DatabaseConnectionUser database,
2879 UpsertClause <Row , RS >? onConflict,
2980 }) {
30- return insert ().onDatabase (database). insert (row, onConflict: onConflict);
81+ return insert ().insert (row, onConflict: onConflict);
3182 }
3283
3384 /// Atomically inserts all [rows] into the table.
@@ -37,14 +88,15 @@ extension TableStatements<
3788 /// the [rows] are in doesn't matter if there are foreign keys between them.
3889 Future <void > insertAll (
3990 Iterable <Insertable <Row >> rows, {
40- required DatabaseConnectionUser database,
4191 UpsertClause <Row , RS >? onConflict,
4292 }) {
43- return database.transaction (
93+ final (rs, db) = _resultSetWithDatabase;
94+
95+ return db.transaction (
4496 options: const TransactionOptions (deferForeignKeys: true ),
4597 () async {
46- await database .batch ((b) {
47- b.insertAll (this , rows, onConflict: onConflict);
98+ await db .batch ((b) {
99+ b.insertAll (rs , rows, onConflict: onConflict);
48100 });
49101 },
50102 );
@@ -54,16 +106,13 @@ extension TableStatements<
54106 /// exists already.
55107 ///
56108 /// Please note that this method is only available on recent sqlite3 versions.
57- /// See also [InsertStatementWithDatabase .insertOnConflictUpdate] .
109+ /// See also [InsertStatement .insertOnConflictUpdate] .
58110 /// By default, only the primary key is used for detect uniqueness violations.
59111 /// If you have further uniqueness constraints, please use the general
60112 /// [insertOne] method with a [DoUpdate] including those columns in its
61113 /// [DoUpdate.target] .
62- Future <int > insertOnConflictUpdate (
63- Insertable <Row > row, {
64- required DatabaseConnectionUser database,
65- }) {
66- return insert ().onDatabase (database).insertOnConflictUpdate (row);
114+ Future <int > insertOnConflictUpdate (Insertable <Row > row) {
115+ return insert ().insertOnConflictUpdate (row);
67116 }
68117
69118 /// Inserts one row into this table and returns it, along with auto-generated
@@ -75,12 +124,9 @@ extension TableStatements<
75124 /// use [insertReturningOrNull] instead.
76125 Future <Row > insertReturning (
77126 Insertable <Row > row, {
78- required DatabaseConnectionUser database,
79127 UpsertClause <Row , RS >? onConflict,
80128 }) {
81- return insert ()
82- .onDatabase (database)
83- .insertReturning (row, onConflict: onConflict);
129+ return insert ().insertReturning (row, onConflict: onConflict);
84130 }
85131
86132 /// Inserts one row into this table and returns it, along with auto-generated
@@ -90,11 +136,36 @@ extension TableStatements<
90136 /// [onConflict] clause with a `where` clause was used), returns `null` .
91137 Future <Row ?> insertReturningOrNull (
92138 Insertable <Row > row, {
93- required DatabaseConnectionUser database,
94139 UpsertClause <Row , RS >? onConflict,
95140 }) {
96- return insert ()
97- .onDatabase (database)
98- .insertReturningOrNull (row, onConflict: onConflict);
141+ return insert ().insertReturningOrNull (row, onConflict: onConflict);
142+ }
143+ }
144+
145+ /// Extension providing the [statements] method for tables and views.
146+ extension GetTableOrViewStatements <
147+ Row extends Object ,
148+ RS extends ResultSet <Row , RS >
149+ >
150+ on ResultSet <Row , RS > {
151+ /// Creates a [TableOrViewStatements] instance that can be used to create
152+ /// common select statements on this table or view.
153+ TableOrViewStatements <Row , RS > statements (DatabaseConnectionUser db) {
154+ return TableOrViewStatements ._((asSelfType (), db));
155+ }
156+ }
157+
158+ /// Extension providing the [statements] method for tables specifically.
159+ extension GetTabletatements <
160+ Row extends Object ,
161+ RS extends GeneratedTable <Row , RS >
162+ >
163+ on GeneratedTable <Row , RS > {
164+ /// Returns a [TableStatements] instance that can be used to create common
165+ /// select, update, insert and delete statements.
166+ TableStatements <Row , RS > statements (DatabaseConnectionUser db) {
167+ return TableStatements ._(
168+ GetTableOrViewStatements <Row , RS >(this ).statements (db),
169+ );
99170 }
100171}
0 commit comments