Skip to content

Commit 1dc065f

Browse files
feat(orm): orm structure
1 parent 6ba8ed6 commit 1dc065f

File tree

11 files changed

+419
-1
lines changed

11 files changed

+419
-1
lines changed

packages/dartseid/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ pubspec.lock
88

99
.idea/
1010

11+
melos_dartseid.iml
1112
# Generated files in example
1213
example/**/*.g.dart

packages/dartseid_orm/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
# Avoid committing pubspec.lock for library packages; see
66
# https://dart.dev/guides/libraries/private-files#pubspeclock.
77
pubspec.lock
8+
9+
melos_dartseid_orm.iml
Lines changed: 331 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,331 @@
1-
class Dorm {}
1+
import 'dart:async';
2+
3+
// This will be initialized with dart orm class after init method is called
4+
final Map<String, Dorm> _dorms = {};
5+
6+
Dorm getDormInstance([String? name]) {
7+
final dorm = _dorms[name ?? "__default"];
8+
if (dorm == null) {
9+
throw StateError(
10+
'Dartseid orm is not initialized. Please run Dorm.init',
11+
);
12+
}
13+
return dorm;
14+
}
15+
16+
class Dorm with DormTable {
17+
final DormAdapterBase adapter;
18+
19+
Dorm._({required this.adapter, String? name}) {
20+
this.name = name ?? "__default";
21+
_dorms[this.name] = this;
22+
}
23+
24+
static Future<Dorm> init({
25+
required DormAdapterBase adapter,
26+
String? name,
27+
}) async {
28+
await adapter.init();
29+
return Dorm._(adapter: adapter, name: name);
30+
}
31+
32+
DormTransaction transaction() {
33+
return adapter.transaction();
34+
}
35+
}
36+
37+
typedef DormTableConverter<T> = ({
38+
FutureOr<T> Function(Map<String, dynamic> json) fromJson,
39+
FutureOr<Map<String, dynamic>> Function() toJson,
40+
});
41+
42+
typedef DormTableFromConverter<T> = ({
43+
FutureOr<T> Function(Map<String, dynamic> json) fromJson,
44+
});
45+
46+
mixin DormTable {
47+
late String name;
48+
final List<DormTableSchema> _tables = [];
49+
50+
late final Dorm _dorm = getDormInstance(name);
51+
52+
DormTableSchema table(
53+
String name,
54+
Map<String, dynamic> schema, {
55+
required DormTableConverter converter,
56+
}) {
57+
final schema =
58+
DormTableSchema(dorm: _dorm, name: name, baseConverter: converter);
59+
_dorm._tables.add(schema);
60+
return schema;
61+
}
62+
63+
DormTableSchema getTable(String name) {
64+
try {
65+
return _tables.firstWhere((element) => element.name == name);
66+
} catch (e) {
67+
throw StateError(
68+
"Table ($name) not found. Please make sure table schema is initialized",
69+
);
70+
}
71+
}
72+
}
73+
74+
class DormTableSchema {
75+
final Dorm dorm;
76+
final String name;
77+
final DormTableConverter baseConverter;
78+
79+
DormTableSchema({
80+
required this.dorm,
81+
required this.name,
82+
required this.baseConverter,
83+
});
84+
85+
DormTransaction transaction() {
86+
return dorm.transaction();
87+
}
88+
89+
void index(Map<String, dynamic> config, {({bool? unique})? options}) {}
90+
91+
DormTableOperator _getTableOperator({
92+
required TableOperator operator,
93+
DormTransaction? transaction,
94+
}) {
95+
return DormTableOperator(
96+
dorm: dorm,
97+
operator: operator,
98+
baseConverter: baseConverter,
99+
transaction: transaction,
100+
);
101+
}
102+
103+
DormTableOperator findOne({DormTransaction? transaction}) {
104+
return _getTableOperator(
105+
operator: TableOperator.findOne,
106+
transaction: transaction,
107+
);
108+
}
109+
110+
DormTableOperator findMany({DormTransaction? transaction}) {
111+
return _getTableOperator(
112+
operator: TableOperator.findMany,
113+
transaction: transaction,
114+
);
115+
}
116+
117+
DormTableOperator create({DormTransaction? transaction}) {
118+
return _getTableOperator(
119+
operator: TableOperator.create,
120+
transaction: transaction,
121+
);
122+
}
123+
124+
DormTableOperator update({DormTransaction? transaction}) {
125+
return _getTableOperator(
126+
operator: TableOperator.update,
127+
transaction: transaction,
128+
);
129+
}
130+
131+
DormTableOperator delete({DormTransaction? transaction}) {
132+
return _getTableOperator(
133+
operator: TableOperator.delete,
134+
transaction: transaction,
135+
);
136+
}
137+
}
138+
139+
sealed class ExecResult<T> {}
140+
141+
class ExecResultData<T> extends ExecResult<T> {
142+
final T data;
143+
144+
ExecResultData(this.data);
145+
}
146+
147+
class ExecResultFailure<T> extends ExecResult<T> {
148+
final DormException exception;
149+
150+
ExecResultFailure(this.exception);
151+
}
152+
153+
class DormTableOperator {
154+
final Dorm _dorm;
155+
final TableOperator _operator;
156+
final DormTableConverter _baseConverter;
157+
final DormTransaction? _transaction;
158+
159+
final List<Map<String, dynamic>> createWithParams = [];
160+
final List<Map<String, dynamic>> updateWithParams = [];
161+
final List<Map<String, dynamic>> whereParams = [];
162+
final List<Map<String, dynamic>> includeParams = [];
163+
final List<Map<String, dynamic>> selectParams = [];
164+
165+
DormTableOperator({
166+
required Dorm dorm,
167+
required TableOperator operator,
168+
required ({
169+
FutureOr<dynamic> Function(Map<String, dynamic>) fromJson,
170+
FutureOr<Map<String, dynamic>> Function() toJson
171+
}) baseConverter,
172+
DormTransaction? transaction,
173+
}) : _transaction = transaction,
174+
_baseConverter = baseConverter,
175+
_operator = operator,
176+
_dorm = dorm;
177+
178+
void createWith() {}
179+
void updateWith() {}
180+
void where() {}
181+
void include() {}
182+
void select() {}
183+
184+
Future<ExecResult> exec<T>({
185+
DormTableFromConverter<T>? converter,
186+
}) async {
187+
try {
188+
final execConverter =
189+
converter != null ? converter.fromJson : _baseConverter.fromJson;
190+
191+
final data = await _dorm.adapter.operate(operator: _operator);
192+
193+
final convertedData = await execConverter(data);
194+
195+
return ExecResultData(convertedData);
196+
} on DormException catch (e) {
197+
return ExecResultFailure(e);
198+
} catch (e) {
199+
return ExecResultFailure(
200+
DormException(originalError: e, message: "Unknown Error"),
201+
);
202+
}
203+
}
204+
}
205+
206+
enum TableOperator {
207+
findOne,
208+
findMany,
209+
create,
210+
update,
211+
delete,
212+
}
213+
214+
class DormException implements Exception {
215+
final Object? originalError;
216+
final String message;
217+
218+
DormException({required this.message, required this.originalError});
219+
}
220+
221+
abstract class DormTransaction {
222+
Future<void> start();
223+
Future<void> commit();
224+
Future<void> rollback();
225+
Future<T> callback<T>(
226+
FutureOr<T> Function(DormTransaction trx) callback,
227+
) async {
228+
try {
229+
await start();
230+
final data = await callback(this);
231+
await commit();
232+
return data;
233+
} catch (e) {
234+
await rollback();
235+
rethrow;
236+
}
237+
}
238+
}
239+
240+
abstract interface class DormAdapterBase {
241+
final dynamic connection;
242+
243+
DormAdapterBase({
244+
required this.connection,
245+
});
246+
247+
Future<void> init();
248+
Future<Map<String, dynamic>> operate({required TableOperator operator});
249+
DormTransaction transaction();
250+
}
251+
252+
class DormMockAdapter implements DormAdapterBase {
253+
@override
254+
final dynamic connection;
255+
256+
DormMockAdapter({
257+
required this.connection,
258+
});
259+
260+
@override
261+
Future<void> init() {
262+
// TODO: implement init
263+
throw UnimplementedError();
264+
}
265+
266+
@override
267+
Future<Map<String, dynamic>> operate({required TableOperator operator}) {
268+
print(operator);
269+
throw UnimplementedError();
270+
}
271+
272+
@override
273+
DormTransaction transaction() {
274+
// TODO: implement transaction
275+
throw UnimplementedError();
276+
}
277+
278+
@override
279+
String a() {
280+
// TODO: implement a
281+
throw UnimplementedError();
282+
}
283+
}
284+
285+
Future<dynamic> dorming() async {
286+
final a = await Dorm.init(
287+
adapter: DormMockAdapter(connection: ""),
288+
);
289+
290+
final t = a.table(
291+
"users",
292+
{
293+
"id": "", // Have a columnmeta class object
294+
"name": "",
295+
},
296+
converter: (
297+
fromJson: (Map<String, dynamic> j) {},
298+
toJson: () => {},
299+
),
300+
);
301+
302+
t.index({"id": 1, "name": 1});
303+
304+
final trx = t.transaction();
305+
306+
final x = t.create();
307+
308+
final data = await trx.callback((trx) async {
309+
final r = t.findOne(transaction: trx)
310+
..where()
311+
..select()
312+
..include();
313+
314+
Future<String> fromJsonFn(Map<String, dynamic> j) async {
315+
return "";
316+
}
317+
318+
final result = await r.exec(converter: (fromJson: fromJsonFn));
319+
320+
return switch (result) {
321+
ExecResultData(data: final data) => data,
322+
ExecResultFailure(exception: final _) => await () async {
323+
await trx.rollback();
324+
throw Exception("I am basic");
325+
}()
326+
};
327+
});
328+
329+
// more dorming
330+
return data;
331+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# https://dart.dev/guides/libraries/private-files
2+
# Created by `dart pub`
3+
.dart_tool/
4+
5+
# Avoid committing pubspec.lock for library packages; see
6+
# https://dart.dev/guides/libraries/private-files#pubspeclock.
7+
pubspec.lock
8+
9+
melos_dartseid_orm_sqlite_adapter.iml
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 1.0.0
2+
3+
- Initial version.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<!--
2+
This README describes the package. If you publish this package to pub.dev,
3+
this README's contents appear on the landing page for your package.
4+
5+
For information about how to write a good package README, see the guide for
6+
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
7+
8+
For general information about developing packages, see the Dart guide for
9+
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
10+
and the Flutter guide for
11+
[developing packages and plugins](https://flutter.dev/developing-packages).
12+
-->
13+
14+
TODO: Put a short description of the package here that helps potential users
15+
know whether this package might be useful for them.
16+
17+
## Features
18+
19+
TODO: List what your package can do. Maybe include images, gifs, or videos.
20+
21+
## Getting started
22+
23+
TODO: List prerequisites and provide or point to information on how to
24+
start using the package.
25+
26+
## Usage
27+
28+
TODO: Include short and useful examples for package users. Add longer examples
29+
to `/example` folder.
30+
31+
```dart
32+
const like = 'sample';
33+
```
34+
35+
## Additional information
36+
37+
TODO: Tell users more about the package: where to find more information, how to
38+
contribute to the package, how to file issues, what response they can expect
39+
from the package authors, and more.

0 commit comments

Comments
 (0)