From 67c9bbd7d58df8d6f16ada2e902c50d761897f91 Mon Sep 17 00:00:00 2001 From: gmpassos Date: Thu, 16 Apr 2026 00:33:42 -0300 Subject: [PATCH 1/2] v1.9.29 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `DBEntityRepository`: - `select`: - Added optimization for `KeyConditionEQ` matcher with a single key matching the entity ID field. - When matched, uses `_selectByID` to fetch the entity by ID and returns a single-element list or empty list accordingly. - Dependency updates: - `vm_service`: ^15.0.2 → ^15.1.0 --- CHANGELOG.md | 10 ++++++++++ lib/src/bones_api_base.dart | 2 +- lib/src/bones_api_entity_db.dart | 24 ++++++++++++++++++++++++ pubspec.yaml | 4 ++-- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f10d0ba..9c3aae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 1.9.29 + +- `DBEntityRepository`: + - `select`: + - Added optimization for `KeyConditionEQ` matcher with a single key matching the entity ID field. + - When matched, uses `_selectByID` to fetch the entity by ID and returns a single-element list or empty list accordingly. + +- Dependency updates: + - `vm_service`: ^15.0.2 → ^15.1.0 + ## 1.9.28 - `SQLGenerator`: diff --git a/lib/src/bones_api_base.dart b/lib/src/bones_api_base.dart index 2f9ca20..b87fb12 100644 --- a/lib/src/bones_api_base.dart +++ b/lib/src/bones_api_base.dart @@ -48,7 +48,7 @@ typedef APILogger = /// Bones API Library class. class BonesAPI { // ignore: constant_identifier_names - static const String VERSION = '1.9.28'; + static const String VERSION = '1.9.29'; static bool _boot = false; diff --git a/lib/src/bones_api_entity_db.dart b/lib/src/bones_api_entity_db.dart index ab1215a..a2b3db4 100644 --- a/lib/src/bones_api_entity_db.dart +++ b/lib/src/bones_api_entity_db.dart @@ -1671,6 +1671,30 @@ class DBEntityRepository extends EntityRepository return _selectAll(transaction, matcher, resolutionRules); } + if (matcher is KeyConditionEQ) { + var keys = matcher.keys; + if (keys.length == 1) { + var conditionKey = matcher.keys.first; + + if (conditionKey is ConditionKeyField) { + var key = conditionKey.name; + var idFieldName = entityHandler.idFieldName(); + + if (idFieldName == key) { + var idValue = matcher.value; + var matcherID = ConditionID(idValue); + + return _selectByID( + transaction, + matcherID, + parameters ?? namedParameters, + resolutionRules, + ).resolveMapped((res) => res != null ? [res] : []); + } + } + } + } + throw UnsupportedError( "Relationship select not supported for: (${matcher.runtimeTypeNameUnsafe}) $matcher @ $tableName ($this)", ); diff --git a/pubspec.yaml b/pubspec.yaml index 5021856..36c9402 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: bones_api description: Bones_API - A powerful API backend framework for Dart. It comes with a built-in HTTP Server, route handler, entity handler, SQL translator, and DB adapters. -version: 1.9.28 +version: 1.9.29 homepage: https://github.com/Colossus-Services/bones_api environment: @@ -61,7 +61,7 @@ dev_dependencies: pubspec: ^2.3.0 #dependency_validator: ^4.1.3 coverage: ^1.15.0 - vm_service: ^15.0.2 + vm_service: ^15.1.0 #dependency_overrides: # shared_map: From 48343bd18680a70a00b72edf28fa7f1e4e2f1244 Mon Sep 17 00:00:00 2001 From: gmpassos Date: Thu, 16 Apr 2026 01:30:14 -0300 Subject: [PATCH 2/2] - `ConditionID`: - Added method `resolveIDValue` to resolve the ID value from parameters or `ConditionParameter`. - `DBEntityRepository`: - Updated `selectIDsBy` and `_selectByID` to use `ConditionID.resolveIDValue` for ID resolution. - `DBObjectDirectoryAdapter`: - Updated `_doCountImpl` and `_doDeleteImpl` to use `ConditionID.resolveIDValue` for ID resolution. - Updated public methods to pass combined parameters (`parameters ?? namedParameters`) to internal implementations. - `DBObjectGCSAdapter`: - Updated `_doCountImpl` and `_doDeleteImpl` to use `ConditionID.resolveIDValue` for ID resolution. - Updated public methods to pass combined parameters (`parameters ?? namedParameters`) to internal implementations. - `DBObjectMemoryAdapter`: - Updated `_doCountImpl` and `_doDeleteImpl` to use `ConditionID.resolveIDValue` for ID resolution. - Updated public methods to pass combined parameters (`parameters ?? namedParameters`) to internal implementations. --- CHANGELOG.md | 16 ++++++++++++++++ lib/src/bones_api_condition.dart | 14 ++++++++++++++ lib/src/bones_api_entity_db.dart | 6 ++++-- .../bones_api_entity_db_object_directory.dart | 8 ++++---- lib/src/bones_api_entity_db_object_gcs.dart | 8 ++++---- lib/src/bones_api_entity_db_object_memory.dart | 8 ++++---- test/bones_api_entity_db_tests_base.dart | 18 ++++++++++++++++++ 7 files changed, 64 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c3aae0..bcbb167 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,26 @@ ## 1.9.29 +- `ConditionID`: + - Added method `resolveIDValue` to resolve the ID value from parameters or `ConditionParameter`. + - `DBEntityRepository`: + - Updated `selectIDsBy` and `_selectByID` to use `ConditionID.resolveIDValue` for ID resolution. - `select`: - Added optimization for `KeyConditionEQ` matcher with a single key matching the entity ID field. - When matched, uses `_selectByID` to fetch the entity by ID and returns a single-element list or empty list accordingly. +- `DBObjectDirectoryAdapter`: + - Updated `_doCountImpl` and `_doDeleteImpl` to use `ConditionID.resolveIDValue` for ID resolution. + - Updated public methods to pass combined parameters (`parameters ?? namedParameters`) to internal implementations. + +- `DBObjectGCSAdapter`: + - Updated `_doCountImpl` and `_doDeleteImpl` to use `ConditionID.resolveIDValue` for ID resolution. + - Updated public methods to pass combined parameters (`parameters ?? namedParameters`) to internal implementations. + +- `DBObjectMemoryAdapter`: + - Updated `_doCountImpl` and `_doDeleteImpl` to use `ConditionID.resolveIDValue` for ID resolution. + - Updated public methods to pass combined parameters (`parameters ?? namedParameters`) to internal implementations. + - Dependency updates: - `vm_service`: ^15.0.2 → ^15.1.0 diff --git a/lib/src/bones_api_condition.dart b/lib/src/bones_api_condition.dart index eeba83d..4bd57d7 100644 --- a/lib/src/bones_api_condition.dart +++ b/lib/src/bones_api_condition.dart @@ -1014,6 +1014,20 @@ class ConditionID extends Condition { ConditionID([this.idValue]) : super._(); + dynamic resolveIDValue({Object? parameters}) { + var id = idValue; + + if (id == null && parameters is O) { + id = getID(parameters); + } + + if (id is ConditionParameter) { + id = id.getValue(parameters: parameters); + } + + return id; + } + @override bool get isIDCondition => true; diff --git a/lib/src/bones_api_entity_db.dart b/lib/src/bones_api_entity_db.dart index a2b3db4..3a06214 100644 --- a/lib/src/bones_api_entity_db.dart +++ b/lib/src/bones_api_entity_db.dart @@ -1710,7 +1710,9 @@ class DBEntityRepository extends EntityRepository int? limit, }) { if (matcher is ConditionID) { - var id = matcher.idValue; + var id = matcher.resolveIDValue( + parameters: parameters ?? namedParameters, + ); return existsID( id, transaction: transaction, @@ -1733,7 +1735,7 @@ class DBEntityRepository extends EntityRepository Object? parameters, EntityResolutionRules? resolutionRules, ) { - var id = matcher.idValue ?? matcher.getID(parameters); + var id = matcher.resolveIDValue(parameters: parameters); if (id == null && parameters != null) { id = matcher.getID(parameters); diff --git a/lib/src/bones_api_entity_db_object_directory.dart b/lib/src/bones_api_entity_db_object_directory.dart index 320c96e..b9bdd87 100644 --- a/lib/src/bones_api_entity_db_object_directory.dart +++ b/lib/src/bones_api_entity_db_object_directory.dart @@ -371,7 +371,7 @@ class DBObjectDirectoryAdapter op, table, matcher, - parameters, + parameters ?? namedParameters, ).resolveMapped((res) => _finishOperation(op, res, preFinish)), ); } @@ -387,7 +387,7 @@ class DBObjectDirectoryAdapter if (matcher != null) { if (matcher is ConditionID) { - var id = matcher.idValue ?? matcher.getID(parameters); + var id = matcher.resolveIDValue(parameters: parameters); var objFile = _resolveObjectFile(table, id); return objFile.existsSync() ? 1 : 0; @@ -558,7 +558,7 @@ class DBObjectDirectoryAdapter op, table, matcher, - parameters, + parameters ?? namedParameters, ).resolveMapped((res) => _finishOperation(op, res, preFinish)), ); @@ -572,7 +572,7 @@ class DBObjectDirectoryAdapter if (!tableDir.existsSync()) return []; if (matcher is ConditionID) { - var id = matcher.idValue ?? matcher.getID(parameters); + var id = matcher.resolveIDValue(parameters: parameters); var objFile = _resolveObjectFile(table, id); if (!objFile.existsSync()) return []; diff --git a/lib/src/bones_api_entity_db_object_gcs.dart b/lib/src/bones_api_entity_db_object_gcs.dart index 367f569..e5f2c91 100644 --- a/lib/src/bones_api_entity_db_object_gcs.dart +++ b/lib/src/bones_api_entity_db_object_gcs.dart @@ -479,7 +479,7 @@ class DBObjectGCSAdapter extends DBObjectAdapter { op, table, matcher, - parameters, + parameters ?? namedParameters, ).resolveMapped((res) => _finishOperation(op, res, preFinish)), ); } @@ -492,7 +492,7 @@ class DBObjectGCSAdapter extends DBObjectAdapter { ) async { if (matcher != null) { if (matcher is ConditionID) { - var id = matcher.idValue ?? matcher.getID(parameters); + var id = matcher.resolveIDValue(parameters: parameters); var objFile = _resolveObjectFilePath(table, id); @@ -646,7 +646,7 @@ class DBObjectGCSAdapter extends DBObjectAdapter { op, table, matcher, - parameters, + parameters ?? namedParameters, ).resolveMapped((res) => _finishOperation(op, res, preFinish)), ); @@ -657,7 +657,7 @@ class DBObjectGCSAdapter extends DBObjectAdapter { Object? parameters, ) async { if (matcher is ConditionID) { - var id = matcher.idValue ?? matcher.getID(parameters); + var id = matcher.resolveIDValue(parameters: parameters); var entry = await _deleteObject(table, id); diff --git a/lib/src/bones_api_entity_db_object_memory.dart b/lib/src/bones_api_entity_db_object_memory.dart index 4fdece4..e9a79d8 100644 --- a/lib/src/bones_api_entity_db_object_memory.dart +++ b/lib/src/bones_api_entity_db_object_memory.dart @@ -438,7 +438,7 @@ class DBObjectMemoryAdapter op, table, matcher, - parameters, + parameters ?? namedParameters, ).resolveMapped((res) => _finishOperation(op, res, preFinish)), ); } @@ -454,7 +454,7 @@ class DBObjectMemoryAdapter if (matcher != null) { if (matcher is ConditionID) { - var id = matcher.idValue ?? matcher.getID(parameters); + var id = matcher.resolveIDValue(parameters: parameters); return map.containsKey(id) ? 1 : 0; } @@ -609,7 +609,7 @@ class DBObjectMemoryAdapter op, table, matcher, - parameters, + parameters ?? namedParameters, ).resolveMapped((res) => _finishOperation(op, res, preFinish)), ); @@ -623,7 +623,7 @@ class DBObjectMemoryAdapter if (map == null) return []; if (matcher is ConditionID) { - var id = matcher.idValue ?? matcher.getID(parameters); + var id = matcher.resolveIDValue(parameters: parameters); var entry = map.remove(id); return entry != null ? [entry] : []; } diff --git a/test/bones_api_entity_db_tests_base.dart b/test/bones_api_entity_db_tests_base.dart index b9d2c84..afd0e2f 100644 --- a/test/bones_api_entity_db_tests_base.dart +++ b/test/bones_api_entity_db_tests_base.dart @@ -791,6 +791,24 @@ Future runAdapterTests( expect((await photoAPIRepository.existsID(png1PixelSha256)), isTrue); + expect( + (await photoAPIRepository.selectByID(png1PixelSha256)), + equals(photo), + ); + + expect( + (await photoAPIRepository.selectByIDs([png1PixelSha256, "nope"])), + equals([photo, null]), + ); + + expect( + (await photoAPIRepository.selectByQuery( + 'id == ?', + parameters: {'id': photo.id}, + )), + equals([photo]), + ); + { var address1 = await addressAPIRepository.selectByID(address.id); expect(address1, isNotNull);