@@ -2,6 +2,7 @@ import 'dart:async';
2
2
import 'dart:convert' ;
3
3
4
4
import 'package:analyzer/dart/element/element.dart' ;
5
+ import 'package:analyzer/dart/element/type.dart' ;
5
6
import 'package:build/build.dart' ;
6
7
import 'package:objectbox/objectbox.dart' as obx;
7
8
import 'package:objectbox/src/bindings/bindings.dart' ;
@@ -91,7 +92,7 @@ class EntityResolver extends Builder {
91
92
}
92
93
93
94
int fieldType, flags = 0 ;
94
- int propUid, indexUid ;
95
+ int propUid;
95
96
96
97
if (_idChecker.hasAnnotationOfExact (f)) {
97
98
if (hasIdProperty) {
@@ -141,72 +142,19 @@ class EntityResolver extends Builder {
141
142
}
142
143
}
143
144
144
- // Index and unique index.
145
- final indexAnnotation = _indexChecker.firstAnnotationOfExact (f);
146
- final hasUniqueAnnotation = _uniqueChecker.hasAnnotationOfExact (f);
147
- if (indexAnnotation != null || hasUniqueAnnotation) {
148
- // Throw if property type does not support any index.
149
- if (fieldType == OBXPropertyType .Float || fieldType == OBXPropertyType .Double || fieldType == OBXPropertyType .ByteVector ) {
150
- throw InvalidGenerationSourceError (
151
- "in target ${elementBare .name }: @Index/@Unique is not supported for type '${f .type .toString ()}' of field '${f .name }'" );
152
- }
153
-
154
- // TODO Throw if index used on Id property.
155
-
156
-
157
- // If available use index type from annotation.
158
- var indexFlag;
159
- if (indexAnnotation != null ) {
160
- indexFlag = indexAnnotation.getField ('flag' ).toIntValue ();
161
- if (indexFlag != null &&
162
- (indexFlag != OBXPropertyFlag .INDEXED
163
- || indexFlag != OBXPropertyFlag .INDEX_HASH
164
- || indexFlag != OBXPropertyFlag .INDEX_HASH64 )) {
165
- throw InvalidGenerationSourceError (
166
- 'in target ${elementBare .name }: @Index flag must be one of [OBXPropertyFlag.INDEXED, OBXPropertyFlag.INDEX_HASH, OBXPropertyFlag.INDEX_HASH64] or none for auto-detection' );
167
- }
168
- }
169
-
170
- // Fall back to index type based on property type.
171
- final supportsHashIndex = fieldType == OBXPropertyType .String ;
172
- if (indexFlag == null ) {
173
- if (supportsHashIndex) {
174
- indexFlag = OBXPropertyFlag .INDEX_HASH ;
175
- } else {
176
- indexFlag = OBXPropertyFlag .INDEXED ;
177
- }
178
- }
179
-
180
- // Throw if HASH or HASH64 is not supported by property type.
181
- if (! supportsHashIndex &&
182
- (indexFlag == OBXPropertyFlag .INDEX_HASH ||
183
- indexFlag == OBXPropertyFlag .INDEX_HASH64 )) {
184
- throw InvalidGenerationSourceError (
185
- "in target ${elementBare .name }: a hash index is not supported for type '${f .type .toString ()}' of field '${f .name }'" );
186
- }
187
-
188
- flags | = indexFlag;
189
- if (hasUniqueAnnotation) {
190
- flags | = OBXPropertyFlag .UNIQUE ;
191
- }
192
- }
193
-
194
145
// create property (do not use readEntity.createProperty in order to avoid generating new ids)
195
- final prop =
196
- ModelProperty ( IdUid . empty (), f.name, fieldType, flags, entity);
146
+ final prop = ModelProperty ( IdUid . empty (), f.name, fieldType,
147
+ flags : flags, entity : entity);
197
148
198
- // TODO test on @Property(...) that uses the proper flags for index
199
- final isIndexer = flags.isIndexer;
200
-
201
- if (isIndexer) {
202
- prop.indexId = indexUid == null ? IdUid .empty () : IdUid (0 , indexUid);
203
- }
149
+ // Index and unique annotation.
150
+ final indexTypeStr =
151
+ processAnnotationIndexUnique (f, fieldType, elementBare, prop);
204
152
205
153
if (propUid != null ) prop.id.uid = propUid;
206
154
entity.properties.add (prop);
207
155
208
156
log.info (
209
- ' ${ isIndexer ? "index " : "" } property ${prop .name }(${prop .id }) type:${prop .type } flags:${prop .flags }' );
157
+ ' property ${prop .name }(${prop .id }) type:${prop .type } flags:${prop .flags } ${ prop . hasIndexFlag () ? "index:${ indexTypeStr }" : "" }' );
210
158
}
211
159
212
160
// some checks on the entity's integrity
@@ -217,4 +165,84 @@ class EntityResolver extends Builder {
217
165
218
166
return entity;
219
167
}
168
+
169
+ String processAnnotationIndexUnique (FieldElement f, int fieldType,
170
+ Element elementBare, obx.ModelProperty prop) {
171
+ obx.IndexType indexType;
172
+
173
+ final indexAnnotation = _indexChecker.firstAnnotationOfExact (f);
174
+ final hasUniqueAnnotation = _uniqueChecker.hasAnnotationOfExact (f);
175
+ if (indexAnnotation == null && ! hasUniqueAnnotation) return null ;
176
+
177
+ // Throw if property type does not support any index.
178
+ if (fieldType == OBXPropertyType .Float ||
179
+ fieldType == OBXPropertyType .Double ||
180
+ fieldType == OBXPropertyType .ByteVector ) {
181
+ throw InvalidGenerationSourceError (
182
+ "in target ${elementBare .name }: @Index/@Unique is not supported for type '${f .type .toString ()}' of field '${f .name }'" );
183
+ }
184
+
185
+ if (prop.hasFlag (OBXPropertyFlags .ID )) {
186
+ throw InvalidGenerationSourceError (
187
+ 'in target ${elementBare .name }: @Index/@Unique is not supported for ID field ${f .name }. IDs are unique by definition and automatically indexed' );
188
+ }
189
+
190
+ // If available use index type from annotation.
191
+ if (indexAnnotation != null && ! indexAnnotation.isNull) {
192
+ // find out @Index(type:) value - its an enum IndexType
193
+ final indexTypeField = indexAnnotation.getField ('type' );
194
+ if (! indexTypeField.isNull) {
195
+ final indexTypeEnumValues = (indexTypeField.type as InterfaceType )
196
+ .element
197
+ .fields
198
+ .where ((f) => f.isEnumConstant)
199
+ .toList ();
200
+
201
+ // Find the index of the matching enum constant.
202
+ for (var i = 0 ; i < indexTypeEnumValues.length; i++ ) {
203
+ if (indexTypeEnumValues[i].computeConstantValue () == indexTypeField) {
204
+ indexType = obx.IndexType .values[i];
205
+ break ;
206
+ }
207
+ }
208
+ }
209
+ }
210
+
211
+ // Fall back to index type based on property type.
212
+ final supportsHashIndex = fieldType == OBXPropertyType .String ;
213
+ if (indexType == null ) {
214
+ if (supportsHashIndex) {
215
+ indexType = obx.IndexType .hash;
216
+ } else {
217
+ indexType = obx.IndexType .value;
218
+ }
219
+ }
220
+
221
+ // Throw if HASH or HASH64 is not supported by property type.
222
+ if (! supportsHashIndex &&
223
+ (indexType == obx.IndexType .hash ||
224
+ indexType == obx.IndexType .hash64)) {
225
+ throw InvalidGenerationSourceError (
226
+ "in target ${elementBare .name }: a hash index is not supported for type '${f .type .toString ()}' of field '${f .name }'" );
227
+ }
228
+
229
+ if (hasUniqueAnnotation) {
230
+ prop.flags | = OBXPropertyFlags .UNIQUE ;
231
+ }
232
+
233
+ switch (indexType) {
234
+ case obx.IndexType .value:
235
+ prop.flags | = OBXPropertyFlags .INDEXED ;
236
+ return 'value' ;
237
+ case obx.IndexType .hash:
238
+ prop.flags | = OBXPropertyFlags .INDEX_HASH ;
239
+ return 'hash' ;
240
+ case obx.IndexType .hash64:
241
+ prop.flags | = OBXPropertyFlags .INDEX_HASH64 ;
242
+ return 'hash64' ;
243
+ default :
244
+ throw InvalidGenerationSourceError (
245
+ 'in target ${elementBare .name }: invalid index type: $indexType ' );
246
+ }
247
+ }
220
248
}
0 commit comments