Skip to content

Commit 4346c81

Browse files
committed
Refactored DBTable annotation. Now it allows to specify target class which allows to split class implementation and annotations.
Added ORM.addAdapter and ORM.setDefaultAdapter.
1 parent 8077e10 commit 4346c81

10 files changed

+302
-91
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
0.1.1
2+
-----
3+
4+
- Refactored DBTable annotation. Now it allows to specify target class which
5+
allows to split class implementation and annotations.
6+
17
0.1.0
28
-----
39

example/example.dart

+8-3
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ dynamic example() async {
8585
'postgres://dart_orm_test:dart_orm_test@localhost:5432/dart_orm_test');
8686
await postgresqlAdapter.connect();
8787

88-
ORM.Model.ormAdapter = postgresqlAdapter;
88+
ORM.addAdapter('postgres', postgresqlAdapter);
89+
ORM.setDefaultAdapter('postgres');
8990

9091
bool migrationResult = await ORM.Migrator.migrate();
9192
assert(migrationResult);
@@ -97,7 +98,8 @@ dynamic example() async {
9798
'mongodb://dart_orm_test:[email protected]/dart_orm_test');
9899
await mongoAdapter.connect();
99100

100-
ORM.Model.ormAdapter = mongoAdapter;
101+
ORM.addAdapter('mongo', mongoAdapter);
102+
ORM.setDefaultAdapter('mongo');
101103

102104
migrationResult = await ORM.Migrator.migrate();
103105
assert(migrationResult);
@@ -108,7 +110,10 @@ dynamic example() async {
108110
MySQLDBAdapter mysqlAdapter = new MySQLDBAdapter(
109111
'mysql://dart_orm_test:dart_orm_test@localhost:3306/dart_orm_test');
110112
await mysqlAdapter.connect();
111-
ORM.Model.ormAdapter = mysqlAdapter;
113+
114+
ORM.addAdapter('mysql', mysqlAdapter);
115+
ORM.setDefaultAdapter('mysql');
116+
112117
migrationResult = await ORM.Migrator.migrate();
113118
assert(migrationResult);
114119

lib/dart_orm.dart

+1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ export 'src/annotations.dart';
55
export 'src/migrator.dart';
66
export 'src/model.dart';
77
export 'src/operations.dart';
8+
export 'src/orm.dart';
89
export 'src/sql_types.dart';
910
export 'src/sql.dart';

lib/src/annotations.dart

+21-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ library dart_orm.annotations;
22

33
import 'dart:mirrors';
44

5-
import 'model.dart';
65
import 'operations.dart';
76

87
/**
@@ -20,9 +19,11 @@ class DBTable {
2019
* One can override this by providing
2120
* String parameter 'tableName' to constructor.
2221
*/
23-
const DBTable([this.name]);
22+
const DBTable([this.name, this.annotationTarget]);
2423

2524
final String name;
25+
26+
final Type annotationTarget;
2627
}
2728

2829
/**
@@ -66,8 +67,20 @@ class AnnotationsParser {
6667
MirrorSystem.getName(metaInstanceMirror.type.simpleName);
6768

6869
if (metaClassName == 'DBTable') {
70+
DBTable dbTableAnnotation = (metaInstanceMirror.reflectee as DBTable);
71+
72+
// if annotation target is not provided then class annotated
73+
// with DBTable is a model itself
6974
Table table = AnnotationsParser.constructTable(classMirror);
70-
ormClasses[modelClassName] = table;
75+
76+
if (dbTableAnnotation.annotationTarget == null) {
77+
ormClasses[modelClassName] = table;
78+
} else {
79+
// we have annotation target so let's get that class
80+
ClassMirror target =
81+
reflectClass(dbTableAnnotation.annotationTarget);
82+
ormClasses[MirrorSystem.getName(target.simpleName)] = table;
83+
}
7184
}
7285
}
7386
}
@@ -111,20 +124,22 @@ class AnnotationsParser {
111124
/**
112125
* Returns [Table] definition object for specified model class instance.
113126
*/
114-
static Table getTableForInstance(Model instance) {
127+
static Table getTableForInstance(dynamic instance) {
115128
InstanceMirror mirror = reflect(instance);
116129
String instanceClassName = MirrorSystem.getName(mirror.type.simpleName);
117130

118131
return ormClasses[instanceClassName];
119132
}
120133

121-
static dynamic getPropertyValueForField(Field field, Model instance) {
134+
/// Returns [field] value for provided model [instance]
135+
static dynamic getPropertyValueForField(Field field, dynamic instance) {
122136
InstanceMirror mirror = reflect(instance);
123137
return mirror.getField(field.constructedFromPropertyName).reflectee;
124138
}
125139

140+
/// Allows setting [field]'s [value] on provided object instance.
126141
static dynamic setPropertyValueForField(
127-
Field field, dynamic value, Model instance) {
142+
Field field, dynamic value, dynamic instance) {
128143
InstanceMirror mirror = reflect(instance);
129144
return mirror.setField(field.constructedFromPropertyName, value);
130145
}

lib/src/migrator.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'adapter.dart';
88
import 'annotations.dart';
99
import 'model.dart';
1010
import 'operations.dart';
11+
import 'orm.dart';
1112

1213
final Logger log = new Logger('Migrator');
1314

@@ -22,7 +23,7 @@ class OrmInfoTable extends Model {
2223

2324
class Migrator {
2425
static Future<bool> migrate() async {
25-
DBAdapter adapter = Model.ormAdapter;
26+
DBAdapter adapter = getDefaultAdapter();
2627

2728
// we store database schema and its version in
2829
// addition table called orm_info_table

lib/src/model.dart

+17-74
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,24 @@ import 'dart:mirrors';
66
import 'adapter.dart';
77
import 'annotations.dart';
88
import 'operations.dart';
9+
import 'orm.dart' as orm;
910

1011
class Model {
1112
Table _tableDefinition;
12-
static DBAdapter _sAdapter;
1313

1414
Model() {
1515
_tableDefinition = AnnotationsParser.getTableForInstance(this);
1616
}
1717

18+
/// Adds adapter that will be used by models.
19+
/// This is deprecated and will be removed in 0.2.0
20+
/// Use [orm.addAdapter] and [orm.setDefaultAdapter] instead.
21+
@deprecated
1822
static void set ormAdapter(DBAdapter adapter) {
19-
_sAdapter = adapter;
23+
orm.addAdapter('modelAdapter', adapter);
24+
orm.setDefaultAdapter('modelAdapter');
2025
}
2126

22-
static DBAdapter get ormAdapter => _sAdapter;
23-
2427
/**
2528
* Returns DBFieldSQL instance
2629
* for primary key defined in this model.
@@ -61,85 +64,26 @@ class Model {
6164
*
6265
* Throws [Exception] if model instance has not-null primary key.
6366
*/
64-
Future insert() async {
65-
var primaryKeyValue = getPrimaryKeyValue();
66-
if (primaryKeyValue != null) {
67-
throw new Exception('insert() should not be called' +
68-
'on instances with not-null primary key value, use update() instead.');
69-
}
70-
71-
Insert insert = new Insert(_tableDefinition);
72-
73-
for (Field field in _tableDefinition.fields) {
74-
if (!field.isPrimaryKey) {
75-
insert.value(field.fieldName,
76-
AnnotationsParser.getPropertyValueForField(field, this));
77-
}
78-
}
79-
80-
var newRecordId = await ormAdapter.insert(insert);
81-
if (this.getPrimaryKeyField() != null) {
82-
this.setPrimaryKeyValue(newRecordId);
83-
}
84-
85-
return newRecordId;
86-
}
67+
Future insert() => orm.insert(this);
8768

8869
/**
8970
* Updates this model instance data on database.
9071
* This model instance primary key should have a not null value.
9172
*
9273
* Throws [Exception] if this model instance is null.
9374
*/
94-
Future update() async {
95-
var primaryKeyValue = getPrimaryKeyValue();
96-
if (primaryKeyValue == null) {
97-
throw new Exception('update() should not be called' +
98-
'on instances with null primary key value, use insert() instead.');
99-
}
100-
101-
Update update = new Update(_tableDefinition);
102-
103-
for (Field field in _tableDefinition.fields) {
104-
var value = AnnotationsParser.getPropertyValueForField(field, this);
105-
if (field.isPrimaryKey) {
106-
update.where(new Equals(field.fieldName, value));
107-
} else {
108-
update.set(field.fieldName, value);
109-
}
110-
}
111-
112-
var updateResult = await ormAdapter.update(update);
113-
return updateResult;
114-
}
75+
Future update() => orm.update(this);
11576

11677
/**
11778
* Deletes this model instance data on database.
11879
* This model instance primary key should have a not null value.
11980
*
12081
* Throws [Exception] if this model instance is null.
12182
*/
122-
Future delete() async {
123-
var primaryKeyValue = getPrimaryKeyValue();
124-
if (primaryKeyValue == null) {
125-
throw new Exception('delete() should not be called' +
126-
'on instances with null primary key value.');
127-
}
128-
129-
Delete delete = new Delete(_tableDefinition);
130-
131-
Field field = getPrimaryKeyField();
132-
if (field != null) {
133-
var value = AnnotationsParser.getPropertyValueForField(field, this);
134-
delete.where(new Equals(field.fieldName, value));
135-
}
136-
137-
var deleteResult = await ormAdapter.delete(delete);
138-
return deleteResult;
139-
}
83+
Future delete() => orm.delete(this);
14084

14185
Future<bool> save() async {
142-
var primaryKeyValue = getPrimaryKeyValue();
86+
var primaryKeyValue = this.getPrimaryKeyValue();
14387

14488
if (primaryKeyValue != null) {
14589
var updateResult = this.update();
@@ -176,7 +120,7 @@ class FindBase extends Select {
176120
}
177121
}
178122

179-
static Future<Model> _executeFindOne(Type modelType, Select sql) async {
123+
static Future _executeFindOne(Type modelType, Select sql) async {
180124
List<Model> foundModels = await _executeFind(modelType, sql);
181125
if (foundModels.length > 0) {
182126
return foundModels.last;
@@ -185,14 +129,13 @@ class FindBase extends Select {
185129
}
186130
}
187131

188-
static Future<List<Model>> _executeFind(
189-
Type modelType, Select selectSql) async {
132+
static Future<List> _executeFind(Type modelType, Select selectSql) async {
190133
Table modelTable = AnnotationsParser.getTableForType(modelType);
191134
ClassMirror modelMirror = reflectClass(modelType);
192135

193-
List<Model> foundInstances = new List<Model>();
136+
List<dynamic> foundInstances = new List<dynamic>();
194137

195-
var rows = await Model.ormAdapter.select(selectSql);
138+
var rows = await orm.getDefaultAdapter().select(selectSql);
196139
for (Map<String, dynamic> row in rows) {
197140
InstanceMirror newInstance =
198141
modelMirror.newInstance(new Symbol(''), [], new Map());
@@ -212,11 +155,11 @@ class FindBase extends Select {
212155
class Find extends FindBase {
213156
Find(Type modelType) : super(modelType);
214157

215-
Future<List<Model>> execute() => FindBase._executeFind(_modelType, this);
158+
Future<List<dynamic>> execute() => FindBase._executeFind(_modelType, this);
216159
}
217160

218161
class FindOne extends FindBase {
219162
FindOne(Type modelType) : super(modelType);
220163

221-
Future<Model> execute() => FindBase._executeFindOne(_modelType, this);
164+
Future<dynamic> execute() => FindBase._executeFindOne(_modelType, this);
222165
}

0 commit comments

Comments
 (0)