Skip to content

Commit

Permalink
Merge pull request #47
Browse files Browse the repository at this point in the history
dart2_3
  • Loading branch information
alextekartik authored Jan 6, 2023
2 parents 8fccf63 + 56bb1fe commit e0cd0f5
Show file tree
Hide file tree
Showing 21 changed files with 362 additions and 53 deletions.
3 changes: 2 additions & 1 deletion idb_shim/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
## 2.1.1-3
## 2.2.0

* Fix keyPath array index creation
* mimic Chrome and prevent cursor delete when using openKeyCursor
* allow keyPath as List<String> when in createObjectStore.

## 2.1.0

Expand Down
9 changes: 0 additions & 9 deletions idb_shim/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@ include: package:lints/recommended.yaml
analyzer:
exclude:
- build/**
strong-mode:
implicit-casts: false
errors:
# treat missing required parameters as a warning (not a hint)
missing_required_param: warning
# treat missing returns as a warning (not a hint)
missing_return: warning
# allow having TODOs in the code
todo: ignore

linter:
rules:
Expand Down
2 changes: 1 addition & 1 deletion idb_shim/lib/idb.dart
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ abstract class Database {
/// This method can be called only within a versionchange transaction.
///
ObjectStore createObjectStore(String name,
{String? keyPath, bool? autoIncrement});
{Object? keyPath, bool? autoIncrement});

///
/// returns a transaction object (Transaction) containing the
Expand Down
16 changes: 12 additions & 4 deletions idb_shim/lib/src/common/common_meta.dart
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ abstract class ObjectStoreWithMetaMixin {
IdbObjectStoreMeta? get meta;

//@override
String? get keyPath => meta!.keyPath;
Object? get keyPath => meta!.keyPath;

//@override
bool get autoIncrement => meta!.autoIncrement;
Expand All @@ -228,7 +228,7 @@ class IdbObjectStoreMeta {
static const String indeciesKey = 'indecies';

final String name;
final String? keyPath;
final Object? keyPath;
final bool autoIncrement;

Iterable<IdbIndexMeta> get indecies => _indecies.values;
Expand Down Expand Up @@ -291,11 +291,19 @@ class IdbObjectStoreMeta {
}
}

static Object? _keyPathAsStringOrList(Object? keyPath) {
if (keyPath is Iterable) {
return keyPath.cast<String>().toList();
} else {
return keyPath?.toString();
}
}

IdbObjectStoreMeta.fromMap(Map<String, Object?> map) //
: this(
//
map[nameKey] as String, //
map[keyPathKey] as String?, //
_keyPathAsStringOrList(map[keyPathKey]),
map[autoIncrementKey] as bool?,
IdbIndexMeta.fromMapList(
((map[indeciesKey]) as List?)?.cast<Map>()));
Expand Down Expand Up @@ -431,7 +439,7 @@ abstract class IndexWithMetaMixin {

class IdbIndexMeta {
final String? name;
final dynamic keyPath;
final Object? keyPath;
final bool unique;
final bool multiEntry;

Expand Down
8 changes: 7 additions & 1 deletion idb_shim/lib/src/common/common_validation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ void checkKeyParam(var key) {
}
}

/// Check a key
void checkKeyValueParam(
{String? keyPath, dynamic key, dynamic value, bool? autoIncrement}) {
{
/** List<String> | String */
Object? keyPath,
dynamic key,
dynamic value,
bool? autoIncrement}) {
if (key != null) {
checkKeyParam(key);
if (keyPath != null) {
Expand Down
85 changes: 80 additions & 5 deletions idb_shim/lib/src/common/common_value.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ library idb_shim_common_value;
import 'dart:convert';

import 'package:idb_shim/idb.dart';
import 'package:idb_shim/src/utils/env_utils.dart';

/// encode a value using JSON.
dynamic encodeValue(dynamic value) {
Expand Down Expand Up @@ -117,13 +118,20 @@ KeyRange keyArrayRangeAt(KeyRange keyRange, int index) {
}

/// return a list if keyPath is an array
Object? mapValueAtKeyPath(Map? map, keyPath) {
///
/// if [keyPath] is a, the list cannot contain null values and null is returned instead.
Object? mapValueAtKeyPath(Map? map, Object? keyPath) {
if (keyPath is String) {
return getMapFieldValue(map, keyPath);
} else if (keyPath is List) {
final keyList = keyPath;
return List.generate(
var keys = List.generate(
keyList.length, (i) => getMapFieldValue(map, keyPath[i] as String));
if (keys.where((element) => element == null).isNotEmpty) {
/// the list cannot contain null values
return null;
}
return keys;
}
throw 'keyPath $keyPath not supported';
}
Expand Down Expand Up @@ -180,12 +188,12 @@ T? getPartsMapValue<T>(Map? map, Iterable<String> parts) {
}

/// Set a field value.
void setMapFieldValue<T>(Map map, String field, T value) {
void setMapFieldValue(Map map, String field, Object value) {
setPartsMapValue(map, getFieldParts(field), value);
}

/// Set a a deep map member value
void setPartsMapValue<T>(Map map, List<String> parts, value) {
void setPartsMapValue(Map map, List<String> parts, Object value) {
for (var i = 0; i < parts.length - 1; i++) {
final part = parts[i];
dynamic sub = map[part];
Expand All @@ -195,5 +203,72 @@ void setPartsMapValue<T>(Map map, List<String> parts, value) {
}
map = sub;
}
map[parts.last] = value;
var key = parts.last;
map[key] = value;
}

/// Common extension
extension IdbValueMapExt on Map {
/// return a list if keyPath is an array
///
/// if [keyPath] is a, the list cannot contain null values and null is returned instead.
Object? getKeyValue(Object? keyPath) {
if (keyPath is String) {
return getFieldValue(keyPath);
} else if (keyPath is List) {
final keyList = keyPath;
var keys = List.generate(
keyList.length, (i) => getFieldValue(keyPath[i] as String));
if (keys.where((element) => element == null).isNotEmpty) {
/// the list cannot contain null values
return null;
}
return keys;
}
throw 'keyPath $keyPath not supported';
}

/// return a list if keyPath is an array
///
/// if [keyPath] is a, the list cannot contain null values and null is returned instead.
void setKeyValue(Object? keyPath, Object value) {
if (keyPath is String) {
return setFieldValue(keyPath, value);
} else if (keyPath is List) {
final keyList = keyPath;
if (isDebug) {
if (value is! List) {
throw ArgumentError.value(value, 'key value', 'is not a list');
}
if (keyPath is! List<String>) {
throw ArgumentError.value(
keyPath, 'keyPath', 'is not a list of string');
}
if (value.length != keyList.length) {
throw ArgumentError.value('$keyPath: $value', 'keyPath: value',
'length do not match (${keyList.length} vs ${value.length}');
}
}

/// value must be a list
final valueList = value as List<Object?>;
assert(keyList.length == valueList.length);
for (var i = 0; i < keyList.length; i++) {
setFieldValue(keyList[i], valueList[i]!);
}
} else {
throw 'keyPath $keyPath not supported';
}
}

/// Get map field helper.
T? getFieldValue<T>(String field) {
return getPartsMapValue(this, getFieldParts(field));
}

/// Set a field value.
void setFieldValue(String field, Object value) {
setPartsMapValue(this, getFieldParts(field), value);
}
}
2 changes: 1 addition & 1 deletion idb_shim/lib/src/logger/logger_database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class DatabaseLogger extends IdbDatabaseBase {

@override
ObjectStore createObjectStore(String name,
{String? keyPath, bool? autoIncrement}) {
{Object? keyPath, bool? autoIncrement}) {
log('createObjectStore($name${getPropertyMapText({
'keyPath': keyPath,
'autoIncrement': autoIncrement
Expand Down
2 changes: 1 addition & 1 deletion idb_shim/lib/src/native/native_database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class DatabaseNative extends IdbDatabaseBase {

@override
ObjectStore createObjectStore(String name,
{String? keyPath, bool? autoIncrement}) {
{Object? keyPath, bool? autoIncrement}) {
return catchNativeError(() {
return ObjectStoreNative(idbDatabase!.createObjectStore(name,
keyPath: keyPath, autoIncrement: autoIncrement));
Expand Down
2 changes: 1 addition & 1 deletion idb_shim/lib/src/sembast/sembast_database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ class DatabaseSembast extends IdbDatabaseBase with DatabaseWithMetaMixin {

@override
ObjectStore createObjectStore(String name,
{String? keyPath, bool? autoIncrement}) {
{Object? keyPath, bool? autoIncrement}) {
final storeMeta = IdbObjectStoreMeta(name, keyPath, autoIncrement);
meta.createObjectStore(storeMeta);
return ObjectStoreSembast(versionChangeTransaction, storeMeta);
Expand Down
2 changes: 1 addition & 1 deletion idb_shim/lib/src/sembast/sembast_object_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class ObjectStoreSembast extends ObjectStore with ObjectStoreWithMetaMixin {
/// Need for add without explicit key
Object fixKeyInValueImpl(Object value, Object key) {
if ((keyPath != null) && (value is Map)) {
return cloneValue(value, keyPath, key);
return cloneValue(value, keyPath as String, key);
}
return value;
}
Expand Down
17 changes: 17 additions & 0 deletions idb_shim/lib/src/utils/env_utils.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
/// Special runtime trick to known whether we are in the javascript world
const idbIsRunningAsJavascript = identical(0, 0.0);

bool? _isRelease;

/// Check whether in release mode
bool? get isRelease {
if (_isRelease == null) {
_isRelease = true;
assert(() {
_isRelease = false;
return true;
}());
}
return _isRelease;
}

/// Check whether running in debug mode
bool get isDebug => !isRelease!;
2 changes: 1 addition & 1 deletion idb_shim/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: idb_shim
version: 2.1.1-3
version: 2.2.0
description: indexed_db dart base interface with implementation for native (browser), file (io) and in memory.
homepage: https://github.com/tekartik/idb_shim.dart/tree/master/idb_shim

Expand Down
28 changes: 20 additions & 8 deletions idb_shim/test/multiplatform/common_meta_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ final IdbObjectStoreMeta idbObjectStoreMeta3 =
IdbObjectStoreMeta('name', null, true);
final IdbObjectStoreMeta idbObjectStoreMeta4 =
IdbObjectStoreMeta('other_name', 'my_key', true);
final IdbObjectStoreMeta idbObjectStoreMetaComposite =
IdbObjectStoreMeta('composite', ['my', 'key'], false);
final List<IdbObjectStoreMeta> idbObjectStoreMetas = [
idbObjectStoreMeta1,
idbObjectStoreMeta2,
idbObjectStoreMeta3
idbObjectStoreMeta3,
];

IdbIndexMeta idbIndexMeta1 = IdbIndexMeta('name', 'my_key', true, true);
Expand Down Expand Up @@ -55,11 +57,18 @@ void defineTests() {
expect(meta1, isNot(meta3));
});

void testStoreRoundTrip(IdbObjectStoreMeta meta) {
var map = meta.toMap();
final newMeta = IdbObjectStoreMeta.fromMap(map);
expect(newMeta, meta);
}

test('store', () {
expect(idbObjectStoreMeta1, idbObjectStoreMeta1Same);
expect(idbObjectStoreMeta1, isNot(idbObjectStoreMeta2));
expect(idbObjectStoreMeta1, isNot(idbObjectStoreMeta3));
expect(idbObjectStoreMeta1, isNot(idbObjectStoreMeta4));
testStoreRoundTrip(idbObjectStoreMeta1);
});

test('index', () {
Expand All @@ -79,8 +88,17 @@ void defineTests() {
final meta3 = idbSimpleObjectStoreMeta.clone();
meta2.putIndex(idbIndexMeta2);
expect(meta1, isNot(meta3));
testStoreRoundTrip(meta1);
});

test('store with keyPath array', () {
final meta = idbObjectStoreMetaComposite;
expect(meta.toMap(), {
'name': 'composite',
'keyPath': ['my', 'key']
});
testStoreRoundTrip(meta);
});
test('store with three indecies', () {
final meta = idbSimpleObjectStoreMeta.clone();
meta.putIndex(IdbIndexMeta('index3', 'keyA', true, false));
Expand All @@ -102,13 +120,7 @@ void defineTests() {
});
});

void testStoreRoundTrip(IdbObjectStoreMeta meta) {
var map = meta.toMap();
final newMeta = IdbObjectStoreMeta.fromMap(map);
expect(newMeta, meta);
}

test('store with keyPath array', () {
test('store with keyPath array index', () {
final meta = idbSimpleObjectStoreMeta.clone();
meta.putIndex(IdbIndexMeta('index3', ['keyA', 'keyB'], true, false));
expect(meta.toMap(), {
Expand Down
11 changes: 10 additions & 1 deletion idb_shim/test/multiplatform/common_validation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void defineTests() {
});

void checkKeyValueParamFail(
{String? keyPath, dynamic key, dynamic value, bool? autoIncrement}) {
{Object? keyPath, dynamic key, dynamic value, bool? autoIncrement}) {
try {
checkKeyValueParam(
keyPath: keyPath,
Expand All @@ -44,6 +44,15 @@ void defineTests() {
fail('$key should fail');
}

test('composite checkKeyValueParam', () {
// DataError: neither keyPath nor autoIncrement set and trying to add object without key.
checkKeyValueParamFail(keyPath: ['my', 'key']);
checkKeyValueParamFail(
keyPath: ['my', 'key'], value: {'my': 1, 'key': null});
checkKeyValueParamFail(keyPath: ['my', 'key'], value: {'my': 1});
checkKeyValueParam(
keyPath: ['my', 'key'], value: {'my': 1, 'key': 'text'});
});
test('checkKeyValueParam', () {
checkKeyValueParamFail(keyPath: 'keyPath', key: 'key', value: {});
checkKeyValueParamFail(
Expand Down
19 changes: 19 additions & 0 deletions idb_shim/test/multiplatform/common_value_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,24 @@ void defineTests() {
expect(keyRange.lower, null);
expect(keyRange.upper, 'John');
});

test('IdbValueMapExt', () {
var map = <String, Object?>{'key': 1};
expect(map.getFieldValue('key'), 1);
expect(map.getKeyValue('key'), 1);
expect(map.getKeyValue(['key']), [1]);
map.setKeyValue('key', 2);
expect(map.getKeyValue(['key']), [2]);
map.setKeyValue(['key'], [3]);
expect(map.getKeyValue('key'), 3);
expect(map, {'key': 3});
map.setKeyValue('my', 'text');
expect(map, {'key': 3, 'my': 'text'});
map.setKeyValue(['my', 'key'], [4, 'text']);
expect(map.getKeyValue(['my', 'key']), [4, 'text']);
expect(map, {'key': 'text', 'my': 4});
map.setFieldValue('my', 1);
expect(map, {'key': 'text', 'my': 1});
});
});
}
Loading

0 comments on commit e0cd0f5

Please sign in to comment.