Skip to content

Commit

Permalink
Add contains functions for String index columns
Browse files Browse the repository at this point in the history
  • Loading branch information
tp committed Nov 6, 2024
1 parent 359df7a commit cd25324
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.4.7

* Add `contains` functions for `String` index columns

## 1.4.6

* Re-enable foreign key constraint for every session
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ packages:
path: ".."
relative: true
source: path
version: "1.4.6"
version: "1.4.7"
leak_tracker:
dependency: transitive
description:
Expand Down
15 changes: 15 additions & 0 deletions lib/src/index_column.dart
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,21 @@ class IndexColumn<T /* entity type */, I /* index type */ > {
// Query operator <=(I value) {
// return lessThanOrEqual(value);
// }

Query contains(dynamic value, {bool caseInsensitive = false}) {
if (value is! String || value is! I) {
throw Exception(
'Can not build query as field "$_field" needs a value of type $String, but got ${value.runtimeType}.',
);
}

return _ContainsStringQuery(
_entity,
_field,
value,
caseInsensitive: caseInsensitive,
);
}
}

bool _typeEqual<T, Y>() => T == Y;
37 changes: 37 additions & 0 deletions lib/src/query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,40 @@ class _LessThanQuery extends Query {
);
}
}

class _ContainsStringQuery extends Query {
_ContainsStringQuery(
this.entity,
this.field,
this.value, {
required this.caseInsensitive,
});

final String entity;
final String field;
final String value;
final bool caseInsensitive;

@override
(String, List) _entityKeysQuery() {
if (caseInsensitive) {
return (
"SELECT `entity` FROM `index` WHERE `type` = ? AND `field` = ? AND `value` LIKE ?",
[
entity,
field,
'%$value%',
],
);
}

return (
"SELECT `entity` FROM `index` WHERE `type` = ? AND `field` = ? AND `value` GLOB ?",
[
entity,
field,
'*$value*',
],
);
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: indexed_entity_store
description: A fast, simple, and synchronous entity store for Flutter applications.
version: 1.4.6
version: 1.4.7
repository: https://github.com/LunaONE/indexed_entity_store

environment:
Expand Down
48 changes: 48 additions & 0 deletions test/indexed_entity_store_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ void main() {
expect(fooStore.getAllOnce(), hasLength(1));

expect(fooStore.queryOnce((cols) => cols['a'].equals('a')), hasLength(1));
// equals is case sensitive
expect(fooStore.queryOnce((cols) => cols['a'].equals('A')), isEmpty);
expect(fooStore.queryOnce((cols) => cols['a'].equals('b')), hasLength(0));

expect(fooStore.queryOnce((cols) => cols['b'].equals(2)), hasLength(1));
Expand Down Expand Up @@ -785,6 +787,52 @@ void main() {
store.queryOnce((cols) => cols['float'].greaterThanOrEqual(1000.0)),
hasLength(1),
);

// String contains
expect(
store.queryOnce((cols) => cols['string'].contains('def')),
hasLength(1),
);
expect(
store.queryOnce((cols) => cols['string'].contains('fau')),
hasLength(1),
);
expect(
store.queryOnce((cols) => cols['string'].contains('lt')),
hasLength(1),
);
expect(
store.queryOnce((cols) => cols['string'].contains('default')),
hasLength(1),
);
expect(
store.queryOnce((cols) => cols['string'].contains('FAU')),
isEmpty, // does not match, as it's case sensitive by default
);
expect(
store.queryOnce(
(cols) => cols['string'].contains('FAU', caseInsensitive: true),
),
hasLength(1), // now matches, as we disabled case-sensitivity
);
expect(
// `null`-able & unsued field
store.queryOnce((cols) => cols['stringOpt'].contains('def')),
isEmpty,
);
expect(
// `null` string field allows the query, but does not have a match yet
store.queryOnce((cols) => cols['stringOpt'].contains('def')),
isEmpty,
);
store.insert(
_AllSupportedIndexTypes.defaultIfNull(stringOpt: 'xxxx'),
);
expect(
// `null` string field with value has a match now
store.queryOnce((cols) => cols['stringOpt'].contains('x')),
hasLength(1),
);
});

test('Limit', () async {
Expand Down

0 comments on commit cd25324

Please sign in to comment.