Skip to content

Commit 37468a5

Browse files
Store config: use to replace store fields #51
1 parent e55d07d commit 37468a5

File tree

3 files changed

+47
-57
lines changed

3 files changed

+47
-57
lines changed

objectbox/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
(or `dart run build_runner build` for Dart Native apps) after updating!
66
* Objects containing `ToOne` and `ToMany` relations can be sent across isolates, e.g. when using
77
`store.runInTransactionAsync`. #340
8+
* `Store.fromReference` and `Store.attach` do not longer accept a null model, which was not
9+
supported anyhow.
810

911
## 1.7.2 (2023-01-31)
1012

objectbox/lib/src/native/store.dart

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import 'dart:typed_data';
99

1010
import 'package:ffi/ffi.dart';
1111
import 'package:meta/meta.dart';
12-
import 'package:objectbox/src/native/version.dart';
1312
import 'package:path/path.dart' as path;
1413

1514
import '../common.dart';
@@ -22,6 +21,7 @@ import 'bindings/helpers.dart';
2221
import 'box.dart';
2322
import 'model.dart';
2423
import 'sync.dart';
24+
import 'version.dart';
2525

2626
part 'observable.dart';
2727

@@ -43,19 +43,26 @@ class Store {
4343
HashMap<int, Type>? _entityTypeById;
4444
final _boxes = HashMap<Type, Box>();
4545

46-
/// Configuration of this for use with [Store._attachByConfiguration].
46+
/// Configuration of this.
47+
/// Is null if this is a minimal store.
48+
/// Can be used with [Store._attachByConfiguration].
4749
late final StoreConfiguration? _configuration;
4850

49-
/// May be null for minimal store, access via [_modelDefinition] with null check.
50-
final ModelDefinition? _defs;
5151
Stream<List<Type>>? _entityChanges;
5252

5353
/// Should be cleared when this closes to free native resources.
5454
final _reader = ReaderWithCBuffer();
5555
Transaction? _tx;
5656

5757
/// Path to the database directory.
58-
final String directoryPath;
58+
String get directoryPath {
59+
final configuration = _configuration;
60+
if (configuration != null) {
61+
return configuration.directoryPath;
62+
} else {
63+
throw StateError("A minimal store does not have a directory path.");
64+
}
65+
}
5966

6067
/// Absolute path to the database directory, used for open check.
6168
final String _absoluteDirectoryPath;
@@ -69,9 +76,6 @@ class Store {
6976
/// remove [_absoluteDirectoryPath] from [_openStoreDirectories].
7077
final bool _closesNativeStore;
7178

72-
/// Default value for string query conditions [caseSensitive] argument.
73-
final bool _queriesCaseSensitiveDefault;
74-
7579
static String _safeDirectoryPath(String? path) =>
7680
(path == null || path.isEmpty) ? defaultDirectoryPath : path;
7781

@@ -157,10 +161,7 @@ class Store {
157161
int? debugFlags,
158162
bool queriesCaseSensitiveDefault = true,
159163
String? macosApplicationGroup})
160-
: _defs = modelDefinition,
161-
_closesNativeStore = true,
162-
_queriesCaseSensitiveDefault = queriesCaseSensitiveDefault,
163-
directoryPath = _safeDirectoryPath(directory),
164+
: _closesNativeStore = true,
164165
_absoluteDirectoryPath =
165166
path.context.canonicalize(_safeDirectoryPath(directory)) {
166167
try {
@@ -181,13 +182,14 @@ class Store {
181182
}
182183
_checkStoreDirectoryNotOpen();
183184
final model = Model(modelDefinition.model);
185+
final safeDirectoryPath = _safeDirectoryPath(directory);
184186

185187
final opt = C.opt();
186188
checkObxPtr(opt, 'failed to create store options');
187189

188190
try {
189191
checkObx(C.opt_model(opt, model.ptr));
190-
final cStr = directoryPath.toNativeUtf8();
192+
final cStr = safeDirectoryPath.toNativeUtf8();
191193
try {
192194
checkObx(C.opt_directory(opt, cStr.cast()));
193195
} finally {
@@ -211,8 +213,8 @@ class Store {
211213
}
212214
if (debugLogs) {
213215
print(
214-
"Opening store (C lib V${libraryVersion()})... path=$directoryPath"
215-
" isOpen=${isOpen(directoryPath)}");
216+
"Opening store (C lib V${libraryVersion()})... path=$safeDirectoryPath"
217+
" isOpen=${isOpen(safeDirectoryPath)}");
216218
}
217219

218220
_cStore = C.store_open(opt);
@@ -227,7 +229,8 @@ class Store {
227229
_reference.setUint64(1 * _int64Size, _ptr.address);
228230

229231
_openStoreDirectories.add(_absoluteDirectoryPath);
230-
_attachConfiguration(_cStore);
232+
_attachConfiguration(_cStore, modelDefinition, safeDirectoryPath,
233+
queriesCaseSensitiveDefault);
231234
_attachFinalizer();
232235
} catch (e) {
233236
_reader.clear();
@@ -272,14 +275,12 @@ class Store {
272275
/// ...
273276
/// }
274277
/// ```
275-
Store.fromReference(this._defs, this._reference,
278+
Store.fromReference(ModelDefinition modelDefinition, this._reference,
276279
{bool queriesCaseSensitiveDefault = true})
277280
:
278281
// Must not close native store twice, only original store is allowed to.
279282
_closesNativeStore = false,
280-
directoryPath = '',
281-
_absoluteDirectoryPath = '',
282-
_queriesCaseSensitiveDefault = queriesCaseSensitiveDefault {
283+
_absoluteDirectoryPath = '' {
283284
// see [reference] for serialization order
284285
final readPid = _reference.getUint64(0 * _int64Size);
285286
if (readPid != pid) {
@@ -293,7 +294,8 @@ class Store {
293294
'Given native pointer is empty');
294295
}
295296

296-
_attachConfiguration(_cStore);
297+
_attachConfiguration(
298+
_cStore, modelDefinition, '', queriesCaseSensitiveDefault);
297299
}
298300

299301
/// Creates a Store clone with minimal functionality given a pointer address
@@ -304,11 +306,8 @@ class Store {
304306
///
305307
/// See [_clone] for details.
306308
Store._minimal(int ptrAddress, {bool queriesCaseSensitiveDefault = true})
307-
: _defs = null,
308-
_closesNativeStore = true,
309-
directoryPath = '',
310-
_absoluteDirectoryPath = '',
311-
_queriesCaseSensitiveDefault = queriesCaseSensitiveDefault {
309+
: _closesNativeStore = true,
310+
_absoluteDirectoryPath = '' {
312311
if (ptrAddress == 0) {
313312
throw ArgumentError.value(
314313
ptrAddress, 'ptrAddress', 'Given native pointer address is invalid');
@@ -329,11 +328,9 @@ class Store {
329328
/// its own lifetime and must also be closed (e.g. before an isolate exits).
330329
/// The actual underlying store is only closed when the last store instance
331330
/// is closed (e.g. when the app exits).
332-
Store.attach(this._defs, String? directoryPath,
331+
Store.attach(ModelDefinition modelDefinition, String? directoryPath,
333332
{bool queriesCaseSensitiveDefault = true})
334333
: _closesNativeStore = true,
335-
_queriesCaseSensitiveDefault = queriesCaseSensitiveDefault,
336-
directoryPath = _safeDirectoryPath(directoryPath),
337334
_absoluteDirectoryPath =
338335
path.context.canonicalize(_safeDirectoryPath(directoryPath)) {
339336
try {
@@ -343,12 +340,12 @@ class Store {
343340
// overlap.
344341
_checkStoreDirectoryNotOpen();
345342

346-
final pathCStr = this.directoryPath.toNativeUtf8();
343+
final safeDirectoryPath = _safeDirectoryPath(directoryPath);
344+
final pathCStr = safeDirectoryPath.toNativeUtf8();
347345
try {
348346
if (debugLogs) {
349347
final isOpen = C.store_is_open(pathCStr.cast());
350-
print(
351-
'Attaching to store... path=${this.directoryPath} isOpen=$isOpen');
348+
print('Attaching to store... path=$safeDirectoryPath isOpen=$isOpen');
352349
}
353350
_cStore = C.store_attach(pathCStr.cast());
354351
} finally {
@@ -361,7 +358,8 @@ class Store {
361358
// Not setting _reference as this is a replacement for obtaining a store
362359
// via reference.
363360

364-
_attachConfiguration(_cStore);
361+
_attachConfiguration(_cStore, modelDefinition, safeDirectoryPath,
362+
queriesCaseSensitiveDefault);
365363
_attachFinalizer();
366364
} catch (e) {
367365
_reader.clear();
@@ -377,12 +375,8 @@ class Store {
377375
/// so [close] this immediately when done using. Closing this will only close
378376
/// the underlying store if it is not opened elsewhere.
379377
Store._attachByConfiguration(StoreConfiguration configuration)
380-
: _defs = configuration.modelDefinition,
381-
_closesNativeStore = true,
382-
directoryPath = configuration.directoryPath,
383-
_absoluteDirectoryPath = '',
384-
_queriesCaseSensitiveDefault =
385-
configuration.queriesCaseSensitiveDefault {
378+
: _closesNativeStore = true,
379+
_absoluteDirectoryPath = '' {
386380
try {
387381
Pointer<OBX_store>? storePtr = C.store_attach_id(configuration.id);
388382
_checkStorePointer(storePtr);
@@ -424,10 +418,11 @@ class Store {
424418
}
425419
}
426420

427-
void _attachConfiguration(Pointer<OBX_store> storePtr) {
421+
void _attachConfiguration(Pointer<OBX_store> storePtr, ModelDefinition model,
422+
String directoryPath, bool queriesCaseSensitiveDefault) {
428423
int id = C.store_id(storePtr);
429-
_configuration = StoreConfiguration._(id, _modelDefinition, directoryPath,
430-
queriesCaseSensitiveDefault: _queriesCaseSensitiveDefault);
424+
_configuration = StoreConfiguration._(
425+
id, model, directoryPath, queriesCaseSensitiveDefault);
431426
}
432427

433428
/// Attach a finalizer (using Dart C API) so when garbage collected, most
@@ -544,7 +539,7 @@ class Store {
544539
}
545540

546541
EntityDefinition<T> _entityDef<T>() {
547-
final binding = _modelDefinition.bindings[T];
542+
final binding = configuration().modelDefinition.bindings[T];
548543
if (binding == null) {
549544
throw ArgumentError('Unknown entity type ' + T.toString());
550545
}
@@ -802,14 +797,6 @@ class Store {
802797
@pragma('vm:prefer-inline')
803798
Pointer<OBX_store> get _ptr =>
804799
isClosed() ? throw StateError('Store is closed') : _cStore;
805-
806-
/// Returns the ModelDefinition of this store, or throws if
807-
/// this is a minimal store.
808-
ModelDefinition get _modelDefinition {
809-
final model = _defs;
810-
if (model == null) throw StateError('Minimal store does not have a model');
811-
return model;
812-
}
813800
}
814801

815802
/// This hides away methods from the public API
@@ -860,7 +847,7 @@ class InternalStoreAccess {
860847
static Map<int, Type> entityTypeById(Store store) {
861848
if (store._entityTypeById == null) {
862849
store._entityTypeById = HashMap<int, Type>();
863-
store._modelDefinition.bindings.forEach(
850+
store.configuration().modelDefinition.bindings.forEach(
864851
(Type entity, EntityDefinition entityDef) =>
865852
store._entityTypeById![entityDef.model.id.id] = entity);
866853
}
@@ -882,7 +869,8 @@ class InternalStoreAccess {
882869

883870
/// String query case-sensitive default
884871
@pragma('vm:prefer-inline')
885-
static bool queryCS(Store store) => store._queriesCaseSensitiveDefault;
872+
static bool queryCS(Store store) =>
873+
store.configuration().queriesCaseSensitiveDefault;
886874

887875
/// The low-level pointer to this store.
888876
@pragma('vm:prefer-inline')

objectbox/lib/src/native/store_config.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ class StoreConfiguration {
66
/// The ID of the store.
77
final int id;
88

9-
/// [Store._modelDefinition]
9+
/// The ModelDefinition of the store.
1010
final ModelDefinition modelDefinition;
1111

12-
/// [Store.directoryPath]
12+
/// Path to the database directory.
1313
final String directoryPath;
1414

15-
/// [Store._queriesCaseSensitiveDefault]
15+
/// Default value for the string query conditions [caseSensitive] argument.
1616
final bool queriesCaseSensitiveDefault;
1717

1818
/// Create a new [StoreConfiguration].
1919
StoreConfiguration._(this.id, this.modelDefinition, this.directoryPath,
20-
{required this.queriesCaseSensitiveDefault});
20+
this.queriesCaseSensitiveDefault);
2121
}

0 commit comments

Comments
 (0)