Skip to content

Commit 5a6e09a

Browse files
author
Ivan Dlugos
committed
add List<String> property support
1 parent 0e3c0d7 commit 5a6e09a

File tree

11 files changed

+109
-44
lines changed

11 files changed

+109
-44
lines changed

generator/integration-tests/basics/1.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ void main() {
5151
// expect(property(model, 'T.tByteVector1').type, OBXPropertyType.ByteVector);
5252
// expect(property(model, 'T.tByteVector2').type, OBXPropertyType.ByteVector);
5353
// expect(property(model, 'T.tByteVector3').type, OBXPropertyType.ByteVector);
54-
// expect(property(model, 'T.tStringVector').type, OBXPropertyType.StringVector);
54+
expect(property(model, 'T.tListString').type, OBXPropertyType.StringVector);
5555
});
5656
}

generator/integration-tests/basics/lib/lib.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,5 @@ class T {
8080
// @Property(type: PropertyType.byteVector)
8181
// Uint8List tByteVector3;
8282

83-
// TODO
84-
// @Property(type: PropertyType.stringVector)
85-
// List<String> tStringVector;
83+
List<String> tListString;
8684
}

generator/lib/src/code_chunks.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ class CodeChunks {
7171
case OBXPropertyType.Relation:
7272
fieldType = 'Integer';
7373
break;
74+
case OBXPropertyType.StringVector:
75+
fieldType = 'StringVector';
76+
break;
7477
default:
7578
throw InvalidGenerationSourceError(
7679
'Unsupported property type (${prop.type}): ${entity.name}.${name}');

generator/lib/src/entity_resolver.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class EntityResolver extends Builder {
103103
}
104104
if (!f.type.isDartCoreInt) {
105105
throw InvalidGenerationSourceError(
106-
"in target ${elementBare.name}: field with @Id property has type '${f.type.toString()}', but it must be 'int'");
106+
"in target ${elementBare.name}: field with @Id property has type '${f.type}', but it must be 'int'");
107107
}
108108

109109
hasIdProperty = true;
@@ -138,9 +138,12 @@ class EntityResolver extends Builder {
138138
// dart: 8 bytes
139139
// ob: 8 bytes
140140
fieldType = OBXPropertyType.Double;
141+
} else if (fieldTypeDart.isDartCoreList &&
142+
listItemType(fieldTypeDart).isDartCoreString) { // List<String>
143+
fieldType = OBXPropertyType.StringVector;
141144
} else {
142145
log.warning(
143-
" skipping property '${f.name}' in entity '${element.name}', as it has the unsupported type '${fieldTypeDart.toString()}'");
146+
" skipping property '${f.name}' in entity '${element.name}', as it has an unsupported type: '${fieldTypeDart}'");
144147
continue;
145148
}
146149
}
@@ -180,7 +183,7 @@ class EntityResolver extends Builder {
180183
fieldType == OBXPropertyType.Double ||
181184
fieldType == OBXPropertyType.ByteVector) {
182185
throw InvalidGenerationSourceError(
183-
"in target ${elementBare.name}: @Index/@Unique is not supported for type '${f.type.toString()}' of field '${f.name}'");
186+
"in target ${elementBare.name}: @Index/@Unique is not supported for type '${f.type}' of field '${f.name}'");
184187
}
185188

186189
if (prop.hasFlag(OBXPropertyFlags.ID)) {
@@ -224,7 +227,7 @@ class EntityResolver extends Builder {
224227
(indexType == obx.IndexType.hash ||
225228
indexType == obx.IndexType.hash64)) {
226229
throw InvalidGenerationSourceError(
227-
"in target ${elementBare.name}: a hash index is not supported for type '${f.type.toString()}' of field '${f.name}'");
230+
"in target ${elementBare.name}: a hash index is not supported for type '${f.type}' of field '${f.name}'");
228231
}
229232

230233
if (hasUniqueAnnotation) {
@@ -265,4 +268,10 @@ class EntityResolver extends Builder {
265268

266269
return null;
267270
}
271+
272+
DartType /*?*/ listItemType(DartType listType) {
273+
final typeArgs =
274+
listType is ParameterizedType ? listType.typeArguments : [];
275+
return typeArgs.length == 1 ? typeArgs[0] : null;
276+
}
268277
}

lib/src/annotations.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ enum PropertyType {
6666
/// dart type=Uint8List, currently not supported
6767
// byteVector,
6868

69-
/// dart type=List<String>, currently not supported
69+
/// dart type=List<String>
70+
/// no need to specify explicitly, just use `List<String> `
7071
// stringVector
7172
}
7273

lib/src/bindings/flatbuffers.dart

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ class OBXFlatbuffersManager<T> {
4949
case OBXPropertyType.String:
5050
offsets[p.id.id] = builder.writeString(propVals[p.name]);
5151
break;
52+
case OBXPropertyType.StringVector:
53+
final stringVector = propVals[p.name] as List<String>;
54+
offsets[p.id.id] = stringVector == null
55+
? null
56+
: builder.writeList(
57+
stringVector.map((str) => builder.writeString(str)).toList());
58+
break;
5259
}
5360
});
5461

@@ -77,18 +84,19 @@ class OBXFlatbuffersManager<T> {
7784
case OBXPropertyType.Long:
7885
builder.addInt64(field, value);
7986
break;
80-
case OBXPropertyType.String:
81-
builder.addOffset(field, offsets[p.id.id] /*!*/);
82-
break;
8387
case OBXPropertyType.Float:
8488
builder.addFloat32(field, value);
8589
break;
8690
case OBXPropertyType.Double:
8791
builder.addFloat64(field, value);
8892
break;
93+
// offset-based fields
94+
case OBXPropertyType.String:
95+
case OBXPropertyType.StringVector:
96+
builder.addOffset(field, offsets[p.id.id] /*!*/);
97+
break;
8998
default:
90-
throw Exception(
91-
'unsupported type: ${p.type}'); // TODO: support more types
99+
throw Exception('unsupported type: ${p.type}');
92100
}
93101
});
94102

@@ -133,9 +141,11 @@ class OBXFlatbuffersManager<T> {
133141
case OBXPropertyType.Double:
134142
propReader = fb.Float64Reader();
135143
break;
144+
case OBXPropertyType.StringVector:
145+
propReader = const fb.ListReader<String>(fb.StringReader());
146+
break;
136147
default:
137-
throw Exception(
138-
'unsupported type: ${p.type}'); // TODO: support more types
148+
throw Exception('unsupported type: ${p.type}');
139149
}
140150

141151
propVals[p.name] = entity.getProp(propReader, (p.id.id + 1) * 2);

lib/src/query/query.dart

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,15 @@ class QueryStringProperty extends QueryProperty {
7878
}
7979

8080
Condition endsWith(String p, {bool caseSensitive = false}) {
81-
return _op(p, ConditionOp.stringEnds, caseSensitive);
81+
return _op(p, ConditionOp.endsWith, caseSensitive);
8282
}
8383

8484
Condition startsWith(String p, {bool caseSensitive = false}) {
85-
return _op(p, ConditionOp.stringStarts, caseSensitive);
85+
return _op(p, ConditionOp.startsWith, caseSensitive);
8686
}
8787

8888
Condition contains(String p, {bool caseSensitive = false}) {
89-
return _op(p, ConditionOp.stringContains, caseSensitive);
89+
return _op(p, ConditionOp.contains, caseSensitive);
9090
}
9191

9292
Condition inside(List<String> list, {bool caseSensitive = false}) {
@@ -235,14 +235,26 @@ class QueryBooleanProperty extends QueryProperty {
235235
// Condition operator ==(bool p) => equals(p); // see issue #43
236236
}
237237

238+
class QueryStringVectorProperty extends QueryProperty {
239+
QueryStringVectorProperty(
240+
{/*required*/ int entityId,
241+
/*required*/ int propertyId,
242+
/*required*/ int obxType})
243+
: super(entityId, propertyId, obxType);
244+
245+
Condition contains(String p, {bool caseSensitive = false}) {
246+
return StringCondition(ConditionOp.contains, this, p, null, caseSensitive);
247+
}
248+
}
249+
238250
enum ConditionOp {
239251
isNull,
240252
notNull,
241253
eq,
242254
notEq,
243-
stringContains,
244-
stringStarts,
245-
stringEnds,
255+
contains,
256+
startsWith,
257+
endsWith,
246258
gt,
247259
greaterOrEq,
248260
lt,
@@ -344,11 +356,14 @@ class StringCondition extends PropertyCondition<String> {
344356
return _op1(builder, bindings.obx_qb_equals_string);
345357
case ConditionOp.notEq:
346358
return _op1(builder, bindings.obx_qb_not_equals_string);
347-
case ConditionOp.stringContains:
348-
return _op1(builder, bindings.obx_qb_contains_string);
349-
case ConditionOp.stringStarts:
359+
case ConditionOp.contains:
360+
final cFn = (_property._type == OBXPropertyType.String)
361+
? bindings.obx_qb_contains_string
362+
: bindings.obx_qb_any_equals_string;
363+
return _op1(builder, cFn);
364+
case ConditionOp.startsWith:
350365
return _op1(builder, bindings.obx_qb_starts_with_string);
351-
case ConditionOp.stringEnds:
366+
case ConditionOp.endsWith:
352367
return _op1(builder, bindings.obx_qb_ends_with_string);
353368
case ConditionOp.lt:
354369
return _op1(builder, bindings.obx_qb_less_than_string);

test/box_test.dart

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ void main() {
3434
});
3535

3636
test('.get() returns the correct item', () {
37-
final int putId = box.put(TestEntity(tString: 'Hello'));
37+
final int putId =
38+
box.put(TestEntity(tString: 'Hello', tStrings: ['foo', 'bar']));
3839
final TestEntity item = box.get(putId) /*!*/;
3940
expect(item.id, equals(putId));
4041
expect(item.tString, equals('Hello'));
42+
expect(item.tStrings, equals(['foo', 'bar']));
4143
});
4244

4345
test('.get() returns null on non-existent item', () {
@@ -146,7 +148,7 @@ void main() {
146148
box.getMany([ids[0], otherId, ids[1]]);
147149
expect(fetchedItems.length, equals(3));
148150
expect(fetchedItems[0] /*!*/ .tString, equals('One'));
149-
expect(fetchedItems[1], equals(null));
151+
expect(fetchedItems[1], isNull);
150152
expect(fetchedItems[2] /*!*/ .tString, equals('Two'));
151153
});
152154

@@ -232,21 +234,21 @@ void main() {
232234
];
233235
final List<TestEntity> fetchedItems =
234236
box.getMany(box.putMany(items)) as List<TestEntity /*!*/ >;
235-
expect(fetchedItems[0].id, isNot(equals(null)));
236-
expect(fetchedItems[0].tLong, equals(null));
237-
expect(fetchedItems[0].tString, equals(null));
238-
expect(fetchedItems[0].tBool, equals(null));
239-
expect(fetchedItems[0].tDouble, equals(null));
240-
expect(fetchedItems[1].id, isNot(equals(null)));
241-
expect(fetchedItems[1].tLong, isNot(equals(null)));
242-
expect(fetchedItems[1].tString, equals(null));
243-
expect(fetchedItems[1].tBool, equals(null));
244-
expect(fetchedItems[1].tDouble, equals(null));
245-
expect(fetchedItems[2].id, isNot(equals(null)));
246-
expect(fetchedItems[2].tLong, equals(null));
247-
expect(fetchedItems[2].tString, isNot(equals(null)));
248-
expect(fetchedItems[2].tBool, equals(null));
249-
expect(fetchedItems[2].tDouble, equals(null));
237+
expect(fetchedItems[0].id, isNotNull);
238+
expect(fetchedItems[0].tLong, isNull);
239+
expect(fetchedItems[0].tString, isNull);
240+
expect(fetchedItems[0].tBool, isNull);
241+
expect(fetchedItems[0].tDouble, isNull);
242+
expect(fetchedItems[1].id, isNotNull);
243+
expect(fetchedItems[1].tLong, isNotNull);
244+
expect(fetchedItems[1].tString, isNull);
245+
expect(fetchedItems[1].tBool, isNull);
246+
expect(fetchedItems[1].tDouble, isNull);
247+
expect(fetchedItems[2].id, isNotNull);
248+
expect(fetchedItems[2].tLong, isNull);
249+
expect(fetchedItems[2].tString, isNotNull);
250+
expect(fetchedItems[2].tBool, isNull);
251+
expect(fetchedItems[2].tDouble, isNull);
250252
});
251253

252254
test('all types are handled correctly', () {

test/entity.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ class TestEntity {
4747
@Property(type: PropertyType.float)
4848
double /*?*/ tFloat;
4949

50+
// OBXPropertyType.StringVector
51+
List<String> /*?*/ tStrings;
52+
5053
TestEntity(
5154
{this.id,
5255
this.tString,
@@ -58,6 +61,7 @@ class TestEntity {
5861
this.tChar,
5962
this.tInt,
6063
this.tFloat,
64+
this.tStrings,
6165
this.ignore});
6266

6367
TestEntity.ignoredExcept(this.tInt) {

test/objectbox-model.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"entities": [
66
{
77
"id": "1:4630700155272683157",
8-
"lastPropertyId": "26:3059114515142777989",
8+
"lastPropertyId": "27:3303202230649375862",
99
"name": "TestEntity",
1010
"flags": 2,
1111
"properties": [
@@ -143,6 +143,11 @@
143143
"type": 6,
144144
"flags": 8,
145145
"indexId": "12:5335419474465474748"
146+
},
147+
{
148+
"id": "27:3303202230649375862",
149+
"name": "tStrings",
150+
"type": 30
146151
}
147152
]
148153
},

0 commit comments

Comments
 (0)