Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
anidotnet committed Dec 27, 2023
1 parent 42c5cab commit 731e9c6
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 0 deletions.
161 changes: 161 additions & 0 deletions flutter-sdk/collection/indexing.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,170 @@ A full-text index is used to search text content in a document. It is useful whe

You can also create your own custom index. You need to implement `NitriteIndexer` interface to create your own custom index. `NitriteIndexer` is a [`NitritePlugin`](../modules/module-system.md#nitriteplugin), so you need to register it using `loadModule()` method while opening a database. During index creation you need to pass the type of the custom index in `IndexOptions` object.

One of such custom index implementation can be found in spatial module. It provides spatial indexing on a collection. More on spatial indexing can be found [here](../modules/spatial.md#spatial-index).

## Creating an Index

You can create an index on a collection using `createIndex()` method. There are several overloaded version of `createIndex()` method. You can create an index on a single field or multiple fields.

### Creating a Unique Index

You can create a unique index on a single field or multiple fields. It takes the name of the fields on which the index will be created as input parameter.

```dart
// create a unique index on a single field
await collection.createIndex(["firstName"]);
// create a unique index on multiple fields
await collection.createIndex(["firstName", "lastName"]);
```

### Creating a Non-unique Index

You can create a non-unique index on a single field or multiple fields by passing the index type as `IndexType.nonUnique` in `IndexOptions` object and the name of the fields on which the index will be created as input parameters.

```dart
// create a non-unique index on a single field
await collection.createIndex(["firstName"], indexOptions(IndexType.nonUnique));
// create a non-unique index on multiple fields
await collection.createIndex(["firstName", "lastName"], indexOptions(IndexType.nonUnique));
```

### Creating a Full-text Index

You can create a full-text index on a single field by passing the index type as `IndexType.fullText` in `IndexOptions` object and the name of the fields on which the index will be created as input parameters.

```dart
// create a full-text index on a single field
await collection.createIndex(["firstName"], indexOptions(IndexType.fullText));
```

!!!warning
Full-text index is not supported on multiple fields.
!!!

### Creating Index on Array Field

Nitrite supports creating index on array field. It will create index on each element of the array. For example, if you have a document like this:

```json
{
"firstName": "John",
"lastName": "Doe",
"age": 30,
"address": "123 Street",
"phones": ["1234567890", "0987654321"]
}
```

You can create index on `phones` field like this:

```dart
// create unique index on array field
await collection.createIndex(["phones"]);
// create non-unique index on array field
await collection.createIndex(["phones"], indexOptions(IndexType.nonUnique));
```

### Creating Index on Nested Field

You can create index on nested field. For example, if you have a document like this:

```json
{
"firstName": "John",
"lastName": "Doe",
"age": 30,
"phones": ["1234567890", "0987654321"],
"address": {
"street": "123 Street",
"city": "New York",
"state": "NY",
"zip": "10021"
}
}
```

You can create index on `street` field like this:

```dart
// create unique index on nested field
await collection.createIndex(["address.street"]);
```

!!!primary
You cannot create index on nested field if the parent field is an array.
!!!

## Rebuilding an Index

You can rebuild an index on a collection using `rebuildIndex()` method. It takes the name of the fields on which the index will be rebuilt as input parameter.

```dart
// rebuild index on a single field
await collection.rebuildIndex(["firstName"]);
// rebuild index on multiple fields
await collection.rebuildIndex(["firstName", "lastName"]);
```

## Dropping an Index

You can drop an index on a collection using `dropIndex()` method. It takes the name of the fields on which the index will be dropped as input parameter.

```dart
// drop index on a single field
await collection.dropIndex(["firstName"]);
// drop index on multiple fields
await collection.dropIndex(["firstName", "lastName"]);
```

## Dropping All Indexes

You can drop all indexes on a collection using `dropAllIndices()` method.

```dart
await collection.dropAllIndices();
```

## Getting All Indexes

You can get all indexes on a collection using `listIndices()` method. It returns a `Future<Collection>` of `IndexDescriptor` object.

```dart
Collection<IndexDescriptor> indexes = await collection.listIndices();
```

### IndexDescriptor

`IndexDescriptor` is a simple class which contains the following information about an index:

- `collectionName`: The name of the collection on which the index is created.
- `indexType`: The type of the index.
- `fields`: A `Fields` object containing the name of the fields on which the index is created.

## Checking If an Index Exists

You can check if an index exists on a collection using `hasIndex()` method. It takes the name of the fields on which the index will be checked as input parameter.

```dart
// check if an index exists on a single field
bool exists = await collection.hasIndex(["firstName"]);
// check if an index exists on multiple fields
bool exists = await collection.hasIndex(["firstName", "lastName"]);
```

## Error Scenarios

The following error scenarios are possible while creating an index:

- If another index of any type is already created on the collection on the same field(s), then it will throw `IndexingException`.
- If a unique index is created on a field and the field contains duplicate value, then it will throw `UniqueConstraintException`.
- If a full-text index is created on multiple fields, then it will throw `IndexingException`.
- If a full-text index is created on a field which is not a `String`, then it will throw `IndexingException`.
- If you try to drop an index which does not exist, then it will throw `IndexingException`.
- If you try to rebuild an index which does not exist, then it will throw `IndexingException`.
147 changes: 147 additions & 0 deletions flutter-sdk/collection/other.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
label: Other Operations
icon: cpu
order: 13
---

## Size of a Collection

You can get the size of a collection using `size` getter. It returns a future of the number of documents in the collection.

```dart
int size = await collection.size;
```

## Clearing a Collection

You can clear all the documents from a collection using `clear()` method. It removes all the documents from the collection and index entries from the indexes. It does not drop the collection.

```dart
await collection.clear();
```

## Dropping a Collection

You can drop a collection using `drop()` method. It removes all the documents from the collection and index entries from the indexes. It also drops all the indexes associated with the collection. It also removes the collection from the database.

```dart
await collection.drop();
```

You can call `isDropped` getter to check if the collection is dropped or not.

```dart
bool isDropped = await collection.isDropped;
```

!!!warning
Any further operation on a dropped collection will throw `NitriteIOException`.
!!!

## Closing a Collection

You can close a collection using `close()` method. Any further operation on a closed collection will throw `NitriteIOException`.

```dart
await collection.close();
```

After closing a collection, you must re-open it via `Nitrite.getCollection()` method to perform any operation on it.

You can call `isOpen` getter to check if the collection is closed or not.

```dart
bool isOpen = await collection.isOpen;
```

## Event Listener

You can register an event listener on a collection to get notified on document changes. The event listener must implement `CollectionEventListener` interface. It will receive `CollectionEventInfo` whenever a document is inserted, updated or removed from the collection.

```dart
collection.subscribe((eventInfo) {
// do something
});
```

You can also remove an event listener from a collection.

```dart
collection.unsubscribe(listener);
```

### CollectionEventInfo

`CollectionEventInfo` contains the following information:

- `item` - the document which is inserted, updated or removed.
- `originator` - the name of the collection on which the event is fired.
- `eventType` - the type of the event. It can be any of the following:
- `EventType.insert`
- `EventType.update`
- `EventType.remove`
- `EventType.indexStart`
- `EventType.indexEnd`
- `timestamp` - the timestamp of the event.

## Attributes

Attributes is a metadata information associated with a collection.

You can get/set attributes on a collection. The attributes are stored in the database and can be retrieved later. The attributes are stored in a special map named `$nitrite_meta_map`.

```dart
// get the attributes
var attributes = await collection.getAttributes();
attributes.set("key", "value");
// save the attributes
await collection.setAttributes(attributes);
// get the attributes
attributes = await collection.getAttributes();
// get the value of a key
var value = attributes["key"];
```

## Processors

Processors are used to process documents before writing them into or after reading them from a collection.

Processors are useful when you want to add some additional information in a document or transform any field before inserting or updating it in a collection. Processors are also useful when you want to validate a document before inserting or updating it in a collection.

Processors are registered on a collection. A collection can have multiple processors. Processors are executed in the order they are registered.

### Registering a Processor

You can register a processor on a collection using `addProcessor()` method. It takes a `Processor` as input parameter.

```dart
class MyProcessor extends Processor {
@override
Document processBeforeWrite(Document document) {
// do something
}
@override
Document processAfterRead(Document document) {
// do something
}
}
// create a processor
var processor = MyProcessor();
// process existing documents, if the collection is not empty
await processor.process(collection);
// register the processor
await collection.addProcessor(processor);
```

### Available Processors

Nitrite provides a `StringFieldEncryptionProcessor` which can be used to encrypt a field before writing it into a collection and decrypt a field after reading it from a collection.

More on this is described in [Support](../support/encryption.md#field-level-encryption).
5 changes: 5 additions & 0 deletions flutter-sdk/repository/codegen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
label: Code Generator
icon: file-code
order: 16
---
12 changes: 12 additions & 0 deletions flutter-sdk/repository/entity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
label: Entity
icon: diamond
order: 15
---

An entity is a Dart object that can be stored in a collection. An entity can be a simple class with a few fields or a complex class with nested objects. Every entity in an `ObjectRepository` is actually converted to a `Document` before storing in the underlying `NitriteCollection`. When an entity is converted to a `Document`, the fields of the entity are mapped to the fields of the `Document`. While retrieving an entity from the `ObjectRepository`, the `Document` is converted back to the entity.

Nitrite uses a `NitriteMapper` implementation to convert an entity to a `Document` and vice versa. By default, Nitrite uses an `EntityConverter` based implementation of `NitriteMapper` to convert an entity to a `Document`. You can also provide your own implementation of `NitriteMapper` to convert an entity to a `Document`.

More on `NitriteMapper` can be found [here](mapper.md).

3 changes: 3 additions & 0 deletions flutter-sdk/repository/index.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
label: Object Repository
icon: container
order: 16
5 changes: 5 additions & 0 deletions flutter-sdk/repository/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
label: Introduction
icon: info
order: 17
---

0 comments on commit 731e9c6

Please sign in to comment.