Skip to content

Commit

Permalink
Merge pull request #41 from IO-Design-Team/feature/generate-adapters-…
Browse files Browse the repository at this point in the history
…refactoring

Refactoring from `generate-adapters` branch
  • Loading branch information
Rexios80 authored Oct 29, 2024
2 parents 0b52d10 + 1c39c34 commit a71edbf
Show file tree
Hide file tree
Showing 36 changed files with 647 additions and 248 deletions.
12 changes: 12 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
coverage:
status:
project:
default:
target: auto
threshold: 5%
base: auto
patch:
default:
target: auto
threshold: 5%
base: auto
135 changes: 73 additions & 62 deletions hive/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@

Hive is a lightweight and blazing fast key-value database written in pure Dart. Inspired by [Bitcask](https://en.wikipedia.org/wiki/Bitcask).

### [Documentation & Samples](https://docs.hivedb.dev/) 📖

If you need queries, multi-isolate support or links between objects check out [Isar Database](https://github.com/isar/isar).

## Migrating from Hive

The `hive_ce` package is a drop in replacement for Hive v2. Make the following replacements in your project:
Expand Down Expand Up @@ -56,22 +52,22 @@ import 'package:hive_ce_flutter/hive_flutter.dart';
- 🎈 **NO** native dependencies
- 🔋 Batteries included

## Getting Started

Check out the [Quick Start](https://docs.hivedb.dev) documentation to get started.

## Usage

You can use Hive just like a map. It is not necessary to await `Futures`.

```dart
var box = Hive.box('myBox');
<!-- embedme readme/usage.dart -->

box.put('name', 'David');
```dart
import 'package:hive_ce/hive.dart';
var name = box.get('name');
void example() {
final box = Hive.box('myBox');
box.put('name', 'David');
final name = box.get('name');
print('Name: $name');
}
print('Name: $name');
```

## BoxCollections
Expand All @@ -86,17 +82,27 @@ transactions on web.
On `dart:io` platforms, there is no performance gain by BoxCollections or Transactions. Only
BoxCollections might be useful for some box hierarchy and development experience.

<!-- embedme readme/box_collections.dart -->

```dart
// Create a box collection
import 'package:hive_ce/hive.dart';
import 'hive_cipher_impl.dart';
void example() async {
// Create a box collection
final collection = await BoxCollection.open(
'MyFirstFluffyBox', // Name of your database
{'cats', 'dogs'}, // Names of your boxes
path: './', // Path where to store your boxes (Only used in Flutter / Dart IO)
key: HiveCipher(), // Key to encrypt your boxes (Only used in Flutter / Dart IO)
// Name of your database
'MyFirstFluffyBox',
// Names of your boxes
{'cats', 'dogs'},
// Path where to store your boxes (Only used in Flutter / Dart IO)
path: './',
// Key to encrypt your boxes (Only used in Flutter / Dart IO)
key: HiveCipherImpl(),
);
// Open your boxes. Optional: Give it a type.
final catsBox = collection.openBox<Map>('cats');
final catsBox = await collection.openBox<Map>('cats');
// Put something in
await catsBox.put('fluffy', {'name': 'Fluffy', 'age': 4});
Expand Down Expand Up @@ -135,67 +141,88 @@ BoxCollections might be useful for some box hierarchy and development experience
boxNames: ['cats'], // By default all boxes become blocked.
readOnly: false,
);
}
```

## Store objects

Hive not only supports primitives, lists and maps but also any Dart object you like. You need to generate a type adapter before you can store objects.
Hive not only supports primitives, lists, and maps but also any Dart object you like. You need to generate type adapters before you can store custom objects.

### Create model classes

<!-- embedme readme/store_objects/person.dart -->

```dart
import 'package:hive_ce/hive.dart';
@HiveType(typeId: 0)
class Person extends HiveObject {
Person({required this.name, required this.age});
@HiveField(0)
String name;
@HiveField(1)
int age;
}
```

Add the following to your pubspec.yaml
### Update `pubspec.yaml`

```yaml
dev_dependencies:
build_runner: latest
hive_ce_generator: latest
```
And run the following command to generate the type adapter
### Run `build_runner`

```bash
flutter pub run build_runner build --delete-conflicting-outputs
dart pub run build_runner build --delete-conflicting-outputs
```

This will generate all of your `TypeAdapter`s as well as a Hive extension to register them all in one go

### Use the Hive registrar

```dart
import 'package:your_package/hive_registrar.g.dart';
import 'dart:io';
import 'package:hive_ce/hive.dart';
import 'package:your_package/hive/hive_registrar.g.dart';
void main() {
final path = Directory.current.path;
Hive
..init(path)
..init(Directory.current.path)
..registerAdapters();
}
```

### Using HiveObject methods

Extending `HiveObject` is optional but it provides handy methods like `save()` and `delete()`.

<!-- embedme readme/store_objects/hive_object.dart -->

```dart
var box = await Hive.openBox('myBox');
import 'package:hive_ce/hive.dart';
import 'person.dart';
void example() async {
final box = await Hive.openBox('myBox');
var person = Person()
..name = 'Dave'
..age = 22;
box.add(person);
final person = Person(name: 'Dave', age: 22);
await box.add(person);
print(box.getAt(0)); // Dave - 22
print(box.getAt(0)); // Dave - 22
person.age = 30;
person.save();
person.age = 30;
await person.save();
print(box.getAt(0)); // Dave - 30
}
print(box.getAt(0)) // Dave - 30
```

## Add fields to objects
Expand All @@ -204,7 +231,11 @@ When adding a new non-nullable field to an existing object, you need to specify

For example, consider an existing database with a `Person` object:

<!-- embedme readme/add_fields/person_1.dart -->

```dart
import 'package:hive_ce/hive.dart';
@HiveType(typeId: 0)
class Person extends HiveObject {
Person({required this.name, required this.age});
Expand All @@ -215,31 +246,16 @@ class Person extends HiveObject {
@HiveField(1)
int age;
}
```

If you want to add a `balance` field:
```dart
@HiveType(typeId: 0)
class Person extends HiveObject {
Person({required this.name, required this.age, required this.balance});
@HiveField(0)
String name;
@HiveField(1)
int age;
@HiveField(2)
int balance;
}
```

Without proper handling, this change will cause null errors in the existing application when accessing the new field.
If you want to add a `balance` field, you must specify a default value or else reading existing data will result in null errors:

To resolve this issue, you can set a default value in the constructor (this requires hive_ce_generator 1.5.0+)
<!-- embedme readme/add_fields/person_2.dart -->

```dart
import 'package:hive_ce/hive.dart';
@HiveType(typeId: 0)
class Person extends HiveObject {
Person({required this.name, required this.age, this.balance = 0});
Expand All @@ -251,8 +267,9 @@ class Person extends HiveObject {
int age;
@HiveField(2)
int balance;
double balance;
}
```

Or specify it in the `HiveField` annotation:
Expand All @@ -264,13 +281,7 @@ int balance;

Alternatively, you can write custom migration code to handle the transition.

After modifying the schema, remember to run the build runner to generate the necessary code:

```console
flutter pub run build_runner build --delete-conflicting-outputs
```

This will update your Hive adapters to reflect the changes in your object structure.
After modifying the model, remember to run `build_runner` to regenerate the TypeAdapters

## Hive ❤️ Flutter

Expand Down
4 changes: 4 additions & 0 deletions hive/example/lib/hive_registrar.g.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Generated by Hive CE
// Do not modify
// Check in to version control

import 'package:hive_ce/hive.dart';
import 'package:example/freezed.dart';
import 'package:example/main.dart';
Expand Down
12 changes: 12 additions & 0 deletions hive/readme/add_fields/person_1.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:hive_ce/hive.dart';

@HiveType(typeId: 0)
class Person extends HiveObject {
Person({required this.name, required this.age});

@HiveField(0)
String name;

@HiveField(1)
int age;
}
15 changes: 15 additions & 0 deletions hive/readme/add_fields/person_2.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:hive_ce/hive.dart';

@HiveType(typeId: 0)
class Person extends HiveObject {
Person({required this.name, required this.age, this.balance = 0});

@HiveField(0)
String name;

@HiveField(1)
int age;

@HiveField(2)
double balance;
}
57 changes: 57 additions & 0 deletions hive/readme/box_collections.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:hive_ce/hive.dart';
import 'hive_cipher_impl.dart';

void example() async {
// Create a box collection
final collection = await BoxCollection.open(
// Name of your database
'MyFirstFluffyBox',
// Names of your boxes
{'cats', 'dogs'},
// Path where to store your boxes (Only used in Flutter / Dart IO)
path: './',
// Key to encrypt your boxes (Only used in Flutter / Dart IO)
key: HiveCipherImpl(),
);

// Open your boxes. Optional: Give it a type.
final catsBox = await collection.openBox<Map>('cats');

// Put something in
await catsBox.put('fluffy', {'name': 'Fluffy', 'age': 4});
await catsBox.put('loki', {'name': 'Loki', 'age': 2});

// Get values of type (immutable) Map?
final loki = await catsBox.get('loki');
print('Loki is ${loki?['age']} years old.');

// Returns a List of values
final cats = await catsBox.getAll(['loki', 'fluffy']);
print(cats);

// Returns a List<String> of all keys
final allCatKeys = await catsBox.getAllKeys();
print(allCatKeys);

// Returns a Map<String, Map> with all keys and entries
final catMap = await catsBox.getAllValues();
print(catMap);

// delete one or more entries
await catsBox.delete('loki');
await catsBox.deleteAll(['loki', 'fluffy']);

// ...or clear the whole box at once
await catsBox.clear();

// Speed up write actions with transactions
await collection.transaction(
() async {
await catsBox.put('fluffy', {'name': 'Fluffy', 'age': 4});
await catsBox.put('loki', {'name': 'Loki', 'age': 2});
// ...
},
boxNames: ['cats'], // By default all boxes become blocked.
readOnly: false,
);
}
31 changes: 31 additions & 0 deletions hive/readme/hive_cipher_impl.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'dart:typed_data';

import 'package:hive_ce/hive.dart';

class HiveCipherImpl extends HiveCipher {
@override
int calculateKeyCrc() => throw UnimplementedError();

@override
int decrypt(
Uint8List inp,
int inpOff,
int inpLength,
Uint8List out,
int outOff,
) =>
throw UnimplementedError();

@override
int encrypt(
Uint8List inp,
int inpOff,
int inpLength,
Uint8List out,
int outOff,
) =>
throw UnimplementedError();

@override
int maxEncryptedSize(Uint8List inp) => throw UnimplementedError();
}
Loading

0 comments on commit a71edbf

Please sign in to comment.