Skip to content

Commit

Permalink
Merge pull request #521 from KalilDev/nnbd
Browse files Browse the repository at this point in the history
[WIP] DO NOT MERGE: Migrate hive to dart nnbd
  • Loading branch information
themisir authored Jan 30, 2021
2 parents 59ad540 + 6772fbd commit 3873fae
Show file tree
Hide file tree
Showing 77 changed files with 1,933 additions and 672 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
strategy:
matrix:
test-platform: [vm, chrome]
dart-channel: [stable, unstable]
dart-channel: [unstable]

steps:
- uses: actions/checkout@v1
Expand All @@ -25,7 +25,7 @@ jobs:
run: |
export PATH="$PATH:/usr/lib/dart/bin"
pub get
pub run test -p ${{ matrix.test-platform }}
pub run --no-sound-null-safety test -p ${{ matrix.test-platform }}
working-directory: hive

check-score:
Expand Down
7 changes: 7 additions & 0 deletions hive/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 2.0.0-nullsafety.0

### Breaking changes
- Migrate to null-safety!
- Update minimum Dart sdk constraint to 2.12.0-0.
- In order to generate null-safe code use hive_generator >= 0.9.0-nullsafety.0

# 1.5.0-pre

### Enhancements
Expand Down
4 changes: 2 additions & 2 deletions hive/lib/src/adapters/ignored_type_adapter.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import 'package:hive/hive.dart';

/// Not part of public API
class IgnoredTypeAdapter<T> implements TypeAdapter<T> {
class IgnoredTypeAdapter<T> implements TypeAdapter<T?> {
const IgnoredTypeAdapter([this.typeId = 0]);

@override
final int typeId;

@override
T read(BinaryReader reader) => null;
T? read(BinaryReader reader) => null;

@override
void write(BinaryWriter writer, obj) {}
Expand Down
4 changes: 2 additions & 2 deletions hive/lib/src/annotations/hive_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class HiveType {
final int typeId;

/// The name of the generated adapter.
final String adapterName;
final String? adapterName;

/// This parameter can be used to keep track of old fieldIds which must not
/// be reused. The generator will throw an error if a legacy fieldId is
Expand All @@ -15,7 +15,7 @@ class HiveType {

/// If [adapterName] is not set, it'll be `"YourClass" + "Adapter"`.
const HiveType({
@required this.typeId,
required this.typeId,
this.adapterName,
//this.legacyFieldIds,
});
Expand Down
16 changes: 8 additions & 8 deletions hive/lib/src/backend/js/backend_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import 'package:hive/src/backend/storage_backend.dart';
class BackendManager implements BackendManagerInterface {
@override
Future<StorageBackend> open(
String name, String path, bool crashRecovery, HiveCipher cipher) async {
String name, String? path, bool crashRecovery, HiveCipher? cipher) async {
var db =
await window.indexedDB.open(name, version: 1, onUpgradeNeeded: (e) {
await window.indexedDB!.open(name, version: 1, onUpgradeNeeded: (e) {
var db = e.target.result as Database;
if (!db.objectStoreNames.contains('box')) {
if (!db.objectStoreNames!.contains('box')) {
db.createObjectStore('box');
}
});
Expand All @@ -22,17 +22,17 @@ class BackendManager implements BackendManagerInterface {
}

@override
Future<void> deleteBox(String name, String path) {
return window.indexedDB.deleteDatabase(name);
Future<void> deleteBox(String name, String? path) {
return window.indexedDB!.deleteDatabase(name);
}

@override
Future<bool> boxExists(String name, String path) async {
Future<bool> boxExists(String name, String? path) async {
// https://stackoverflow.com/a/17473952
try {
var _exists = true;
await window.indexedDB.open(name, version: 1, onUpgradeNeeded: (e) {
e.target.transaction.abort();
await window.indexedDB!.open(name, version: 1, onUpgradeNeeded: (e) {
e.target.transaction!.abort();
_exists = false;
});
return _exists;
Expand Down
22 changes: 12 additions & 10 deletions hive/lib/src/backend/js/storage_backend_js.dart
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
import 'dart:async';
import 'dart:html';
import 'dart:indexed_db';
import 'dart:typed_data';
import 'dart:js_util';
import 'dart:typed_data';

import 'package:hive/hive.dart';
import 'package:hive/src/backend/storage_backend.dart';
import 'package:hive/src/binary/binary_reader_impl.dart';
import 'package:hive/src/binary/binary_writer_impl.dart';
import 'package:hive/src/binary/frame.dart';
import 'package:hive/src/box/keystore.dart';
import 'package:hive/src/registry/type_registry_impl.dart';
import 'package:meta/meta.dart';

/// Handles all IndexedDB related tasks
class StorageBackendJs extends StorageBackend {
static const _bytePrefix = [0x90, 0xA9];
final Database _db;
final HiveCipher _cipher;
final HiveCipher? _cipher;

TypeRegistry _registry;

/// Not part of public API
StorageBackendJs(this._db, this._cipher, [this._registry]);
StorageBackendJs(this._db, this._cipher,
[this._registry = TypeRegistryImpl.nullImpl]);

@override
String get path => null;
String? get path => null;

@override
bool supportsCompaction = false;
Expand Down Expand Up @@ -62,7 +64,7 @@ class StorageBackendJs extends StorageBackend {
if (_cipher == null) {
frameWriter.write(value);
} else {
frameWriter.writeEncrypted(value, _cipher);
frameWriter.writeEncrypted(value, _cipher!);
}

var bytes = frameWriter.toBytes();
Expand All @@ -81,7 +83,7 @@ class StorageBackendJs extends StorageBackend {
if (_cipher == null) {
return reader.read();
} else {
return reader.readEncrypted(_cipher);
return reader.readEncrypted(_cipher!);
}
} else {
return bytes;
Expand All @@ -108,10 +110,10 @@ class StorageBackendJs extends StorageBackend {
var completer = Completer<List<dynamic>>();
var request = getStore(false).getAllKeys(null);
request.onSuccess.listen((_) {
completer.complete(request.result as List<dynamic>);
completer.complete(request.result as List<dynamic>?);
});
request.onError.listen((_) {
completer.completeError(request.error);
completer.completeError(request.error!);
});
return completer.future;
} else {
Expand All @@ -132,7 +134,7 @@ class StorageBackendJs extends StorageBackend {
completer.complete(values);
});
request.onError.listen((_) {
completer.completeError(request.error);
completer.completeError(request.error!);
});
return completer.future;
} else {
Expand Down Expand Up @@ -197,6 +199,6 @@ class StorageBackendJs extends StorageBackend {

@override
Future<void> deleteFromDisk() {
return window.indexedDB.deleteDatabase(_db.name);
return window.indexedDB!.deleteDatabase(_db.name!);
}
}
6 changes: 3 additions & 3 deletions hive/lib/src/backend/storage_backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export 'package:hive/src/backend/stub/backend_manager.dart'
/// Abstract storage backend
abstract class StorageBackend {
/// The path where the database is stored
String get path;
String? get path;

/// Whether the database can be compacted
bool get supportsCompaction;
Expand Down Expand Up @@ -43,8 +43,8 @@ abstract class BackendManagerInterface {
String name, String path, bool crashRecovery, HiveCipher cipher);

/// Deletes database
Future<void> deleteBox(String name, String path);
Future<void> deleteBox(String name, String? path);

/// Checks if box exists
Future<bool> boxExists(String name, String path);
Future<bool> boxExists(String name, String? path);
}
22 changes: 14 additions & 8 deletions hive/lib/src/backend/storage_backend_memory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,32 @@ import 'package:hive/src/box/keystore.dart';

/// In-memory Storage backend
class StorageBackendMemory extends StorageBackend {
final HiveCipher _cipher;
final HiveCipher? _cipher;

final FrameHelper _frameHelper;

Uint8List _bytes;
Uint8List? _bytes;

/// Not part of public API
StorageBackendMemory(this._bytes, this._cipher)
: _frameHelper = FrameHelper();
StorageBackendMemory(Uint8List? bytes, this._cipher)
: _bytes = bytes,
_frameHelper = FrameHelper();

@override
String get path => null;
String? get path => null;

@override
bool supportsCompaction = false;

@override
Future<void> initialize(TypeRegistry registry, Keystore keystore, bool lazy) {
var recoveryOffset =
_frameHelper.framesFromBytes(_bytes, keystore, registry, _cipher);
Future<void> initialize(
TypeRegistry registry, Keystore? keystore, bool lazy) {
var recoveryOffset = _frameHelper.framesFromBytes(
_bytes!, // Initialized at constructor and nulled after initialization
keystore,
registry,
_cipher,
);

if (recoveryOffset != -1) {
throw HiveError('Wrong checksum in bytes. Box may be corrupted.');
Expand Down
6 changes: 3 additions & 3 deletions hive/lib/src/backend/stub/backend_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import 'package:hive/src/backend/storage_backend.dart';
class BackendManager implements BackendManagerInterface {
@override
Future<StorageBackend> open(
String name, String path, bool crashRecovery, HiveCipher cipher) {
String name, String? path, bool crashRecovery, HiveCipher? cipher) {
throw UnimplementedError();
}

@override
Future<void> deleteBox(String name, String path) {
Future<void> deleteBox(String name, String? path) {
throw UnimplementedError();
}

@override
Future<bool> boxExists(String name, String path) {
Future<bool> boxExists(String name, String? path) {
throw UnimplementedError();
}
}
8 changes: 5 additions & 3 deletions hive/lib/src/backend/vm/backend_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class BackendManager implements BackendManagerInterface {

@override
Future<StorageBackend> open(
String name, String path, bool crashRecovery, HiveCipher cipher) async {
String name, String? path, bool crashRecovery, HiveCipher? cipher) async {
if (path == null) {
throw HiveError('You need to initialize Hive or '
'provide a path to store the box.');
Expand Down Expand Up @@ -50,7 +50,8 @@ class BackendManager implements BackendManagerInterface {
}

@override
Future<void> deleteBox(String name, String path) async {
Future<void> deleteBox(String name, String? path) async {
ArgumentError.checkNotNull(path, 'path');
await _deleteFileIfExists(File('$path$_delimiter$name.hive'));
await _deleteFileIfExists(File('$path$_delimiter$name.hivec'));
await _deleteFileIfExists(File('$path$_delimiter$name.lock'));
Expand All @@ -63,7 +64,8 @@ class BackendManager implements BackendManagerInterface {
}

@override
Future<bool> boxExists(String name, String path) async {
Future<bool> boxExists(String name, String? path) async {
ArgumentError.checkNotNull(path, 'path');
return await File('$path$_delimiter$name.hive').exists() ||
await File('$path$_delimiter$name.hivec').exists() ||
await File('$path$_delimiter$name.lock').exists();
Expand Down
26 changes: 15 additions & 11 deletions hive/lib/src/backend/vm/storage_backend_vm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,34 @@ class StorageBackendVm extends StorageBackend {
final File _file;
final File _lockFile;
final bool _crashRecovery;
final HiveCipher _cipher;
final HiveCipher? _cipher;
final FrameIoHelper _frameHelper;

final ReadWriteSync _sync;

/// Not part of public API
///
/// Not `late final` for testing
@visibleForTesting
RandomAccessFile readRaf;
late RandomAccessFile readRaf;

/// Not part of public API
///
/// Not `late final` for testing
@visibleForTesting
RandomAccessFile writeRaf;
late RandomAccessFile writeRaf;

/// Not part of public API
@visibleForTesting
RandomAccessFile lockRaf;
late RandomAccessFile lockRaf;

/// Not part of public API
@visibleForTesting
int writeOffset = 0;

/// Not part of public API
@visibleForTesting
TypeRegistry registry;
late final TypeRegistry registry;

bool _compactionScheduled = false;

Expand Down Expand Up @@ -100,7 +104,7 @@ class StorageBackendVm extends StorageBackend {
return _sync.syncRead(() async {
await readRaf.setPosition(frame.offset);

var bytes = await readRaf.read(frame.length);
var bytes = await readRaf.read(frame.length!);

var reader = BinaryReaderImpl(bytes, registry);
var readFrame = reader.readFrame(cipher: _cipher, lazy: false);
Expand Down Expand Up @@ -132,7 +136,7 @@ class StorageBackendVm extends StorageBackend {

for (var frame in frames) {
frame.offset = writeOffset;
writeOffset += frame.length;
writeOffset += frame.length!;
}
});
}
Expand Down Expand Up @@ -166,12 +170,12 @@ class StorageBackendVm extends StorageBackend {
reader.skip(skip);
}

if (reader.remainingInBuffer < frame.length) {
if (await reader.loadBytes(frame.length) < frame.length) {
if (reader.remainingInBuffer < frame.length!) {
if (await reader.loadBytes(frame.length!) < frame.length!) {
throw HiveError('Could not compact box: Unexpected EOF.');
}
}
await writer.write(reader.viewBytes(frame.length));
await writer.write(reader.viewBytes(frame.length!));
}
await writer.flush();
} finally {
Expand All @@ -187,7 +191,7 @@ class StorageBackendVm extends StorageBackend {
for (var frame in sortedFrames) {
if (frame.offset == -1) continue;
frame.offset = offset;
offset += frame.length;
offset += frame.length!;
}
_compactionScheduled = false;
});
Expand Down
Loading

0 comments on commit 3873fae

Please sign in to comment.