Skip to content

Commit

Permalink
refactor: Redefine terminology, replacing 'table' with 'scheme' and '…
Browse files Browse the repository at this point in the history
…column' with 'property'
  • Loading branch information
izure1 committed Jun 28, 2024
1 parent 646d88a commit 5c2d5f7
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 48 deletions.
36 changes: 19 additions & 17 deletions docs/document/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This document covers the usage of the **document-oriented** database in **tissue-roll**.

The document database in **tissue-roll** allows you to insert data in **JSON** format. Specify each column in TypeScript.
The document database in **tissue-roll** allows you to insert data in **JSON** format. Specify each property in TypeScript.

If this is not the database you were looking for, please check the [key-value](../core/README.md) database.

Expand All @@ -15,7 +15,7 @@ import { TissueRollDocument } from 'tissue-roll'
const db = TissueRollDocument.Open({
path: 'my_file_path.db',
version: 0,
table: {
scheme: {
name: {
default: () => 'Anonymous',
validate: (v) => typeof v === 'string'
Expand Down Expand Up @@ -60,9 +60,9 @@ If there are many write/update operations in the database, it's recommended to s

*Note that this value cannot be modified after the database is created*, so choose carefully. If you're unsure, you can leave it as the default, which is **1024**.

## Reserved table column names
## Reserved document property names

First of all, when inserting a document in **TissueRollDocument**, the following columns are automatically added. These values cannot be overwritten, so be careful when naming table columns.
First of all, when inserting a document in **TissueRollDocument**, the following properties are automatically added. These values cannot be overwritten, so be careful when naming document properties.

* `documentIndex`
The index when the document was inserted. This value is automatically added when inserted into the database.
Expand All @@ -77,13 +77,13 @@ First of all, when inserting a document in **TissueRollDocument**, the following

### Explicit Type Specification

The table is distinguished by key-value, where the key is the column name of the table, and the value has default and validate properties.
The scheme is distinguished by key-value, where the key is the property name of the scheme, and the value has default and validate properties.

```typescript
const db = TissueRollDocument.Open({
path: 'my_file_path.db',
version: 0,
table: {
scheme: {
name: {
default: () => 'Anonymous',
validate: (v) => typeof v === 'string'
Expand All @@ -103,9 +103,9 @@ const db = TissueRollDocument.Open({

#### default (required)

The default property is a function that returns one of the **string**, **number**, **boolean**, or **null** types, and is used to automatically generate a default value for a column that is omitted when inserting or updating a document.
The default property is a function that returns one of the **string**, **number**, **boolean**, or **null** types, and is used to automatically generate a default value for a property that is omitted when inserting or updating a document.

For example, if the table structure is changed and a new column is added, all documents inserted before will have this function called and a default value inserted.
For example, if the scheme structure is changed and a new property is added, all documents inserted before will have this function called and a default value inserted.

#### validate (optional)

Expand All @@ -115,29 +115,31 @@ It is a function that checks the validity of the value when inserting or updatin

For example, if you want the **name** attribute to accept only strings, you can implement it like this: `validate: (v) => typeof v === 'string'`.

### Table structure change
### Scheme structure change

However, you may want to extend the columns of the table. For example, let's say you want to add a **student** column that you didn't have before.
However, you may want to extend the properties of the scheme. For example, let's say you want to add a **student** property that you didn't have before.

```typescript
table: {
{
scheme: {
...
// If the table structure has been modified, you must increment the version!
version: 1,
student: {
default: () => true,
validate: (v) => typeof v === 'boolean'
}
}
// If the scheme structure has been modified, you must increment the version!
version: 1
}
```

In this case, you can simply add the **student** column to the table property. Then, increment the **version** number. **TissueRollDocument** considers the table to be modified **if this version value is higher than the previous one**, and updates all existing records to maintain consistency.
In this case, you can simply add the **student** to the scheme property. Then, increment the **version** number. **TissueRollDocument** considers the scheme to be modified **if this version value is higher than the previous one**, and updates all existing records to maintain consistency.

And the **student** column will be set to the default value because it did not exist in the documents that were inserted before.
And the **student** property will be set to the default value because it did not exist in the documents that were inserted before.

#### Caution when deleting columns
#### Caution when deleting properties

When migrating to delete an existing column, columns that do not exist in the latest table among documents inserted in the past are deleted from the database. Since data loss occurs, please make sure to back up your database.
When migrating to delete an existing property, properties that do not exist in the latest scheme among documents inserted in the past are deleted from the database. Since data loss occurs, please make sure to back up your database.

#### Performance caution when migrating

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tissue-roll",
"version": "5.0.2",
"version": "5.0.3",
"description": "Very simple read/write database with a no-sql.",
"main": "dist/cjs/index.cjs",
"module": "dist/esm/index.mjs",
Expand Down
58 changes: 29 additions & 29 deletions src/document/TissueRollDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export type SupportedType = PrimitiveType|SupportedType[]|{ [key: string]: Suppo

export interface TissueRollDocumentRoot {
verify: 'TissueRollDocument'
tableVersion: number
schemeVersion: number
reassignments: string[]
head: Record<string, SerializeStrategyHead|null>
}
Expand Down Expand Up @@ -109,15 +109,15 @@ interface TissueRollDocumentField {
validate?: (v: SupportedType) => boolean
}

interface TissueRollDocumentTable {
interface TissueRollDocumentScheme {
[key: string]: TissueRollDocumentField
}

type TissueRollDocumentTableType<T extends TissueRollDocumentTable> = {
type TissueRollDocumentSchemeType<T extends TissueRollDocumentScheme> = {
[K in keyof T]: ReturnType<T[K]['default']>
}

interface TissueRollDocumentCreateOption<T extends TissueRollDocumentTable> {
interface TissueRollDocumentCreateOption<T extends TissueRollDocumentScheme> {
/**
* This is the path where the database file will be created.
*/
Expand All @@ -127,13 +127,13 @@ interface TissueRollDocumentCreateOption<T extends TissueRollDocumentTable> {
*/
version: number
/**
* The fields of the database table and their validation functions.
* The fields of the database scheme and their validation functions.
* The property names become field names, and their values perform validation when inserting or updating values.
* Please refer to the example below.
* ```
* const db = TissueRollDocument.Open({
* path: 'my-db-path/database.db',
* table: {
* scheme: {
* id: {
* default: () => uuid(),
* validate: (v) => isUUID(v)
Expand All @@ -149,7 +149,7 @@ interface TissueRollDocumentCreateOption<T extends TissueRollDocumentTable> {
* you can easily implement these validation checks.
* Please refer to it for assistance.
*/
table: T
scheme: T
/**
* This is the maximum data size a single page in the database can hold. The default is `1024`. If this value is too large or too small, it can affect performance.
*/
Expand Down Expand Up @@ -206,19 +206,19 @@ export class TissueRollDocument<T extends TissueRollDocumentRecordShape> {
* @param option The database creation options.
*/
static Create<
T extends TissueRollDocumentTable
>(option: TissueRollDocumentCreateOption<T>): TissueRollDocument<TissueRollDocumentTableType<T>> {
T extends TissueRollDocumentScheme
>(option: TissueRollDocumentCreateOption<T>): TissueRollDocument<TissueRollDocumentSchemeType<T>> {
const {
path,
version,
table,
scheme,
payloadSize = 1024,
overwrite = false
} = option
const db = TissueRoll.Create(path, payloadSize, overwrite)
const docRoot: TissueRollDocumentRoot = {
verify: TissueRollDocument.DB_NAME,
tableVersion: 0,
schemeVersion: 0,
reassignments: [],
head: {},
}
Expand All @@ -229,20 +229,20 @@ export class TissueRollDocument<T extends TissueRollDocumentRecordShape> {
)
db.update(rootId, JSON.stringify(docRoot))

return new TissueRollDocument(db, rootId, docRoot, table, version, 0)
return new TissueRollDocument(db, rootId, docRoot, scheme, version, 0)
}

/**
* It opens or creates a database file at the specified path.
* @param option The database creation options.
*/
static Open<
T extends TissueRollDocumentTable
>(option: TissueRollDocumentCreateOption<T>): TissueRollDocument<TissueRollDocumentTableType<T>> {
T extends TissueRollDocumentScheme
>(option: TissueRollDocumentCreateOption<T>): TissueRollDocument<TissueRollDocumentSchemeType<T>> {
const {
path,
version,
table,
scheme,
payloadSize = 1024
} = option
// 파일이 존재하지 않을 경우
Expand All @@ -258,16 +258,16 @@ export class TissueRollDocument<T extends TissueRollDocumentRecordShape> {
const record = db.getRecords(1)[0]
const docRoot = TissueRollDocument.Verify(path, record.payload)

return new TissueRollDocument(db, record.header.id, docRoot, table, version, 0)
return new TissueRollDocument(db, record.header.id, docRoot, scheme, version, 0)
}

protected readonly db: TissueRoll
protected readonly rootId: string
protected readonly order: number
protected readonly comparator: TissueRollComparator
protected readonly locker: DelayedExecution
protected readonly table: TissueRollDocumentTable
protected readonly tableVersion: number
protected readonly scheme: TissueRollDocumentScheme
protected readonly schemeVersion: number
protected lock: boolean
private readonly _trees: ReturnType<TissueRollDocument<T>['_createTreesCache']>
private readonly _document: ReturnType<TissueRollDocument<T>['_createDocumentCache']>
Expand All @@ -281,17 +281,17 @@ export class TissueRollDocument<T extends TissueRollDocumentRecordShape> {
db: TissueRoll,
rootId: string,
root: TissueRollDocumentRoot,
table: TissueRollDocumentTable,
tableVersion: number,
scheme: TissueRollDocumentScheme,
schemeVersion: number,
writeBack: number
) {
this.db = db
this.rootId = rootId
this.order = Math.max(TissueRollDocument.OrderN(db.metadata.payloadSize, 40), 4)
this.comparator = new TissueRollComparator()
this.locker = new DelayedExecution(writeBack)
this.tableVersion = tableVersion
this.table = table
this.schemeVersion = schemeVersion
this.scheme = scheme
this.lock = false
this._root = root
this._trees = this._createTreesCache()
Expand All @@ -303,9 +303,9 @@ export class TissueRollDocument<T extends TissueRollDocumentRecordShape> {
count,
}

// Needed to alter table
if (this._root.tableVersion < tableVersion) {
this._root.tableVersion = tableVersion
// Needed to alter scheme
if (this._root.schemeVersion < schemeVersion) {
this._root.schemeVersion = schemeVersion
this.updateRoot(this._root)
this._callInternalUpdate(
{},
Expand Down Expand Up @@ -392,8 +392,8 @@ export class TissueRollDocument<T extends TissueRollDocumentRecordShape> {
record: Partial<T>
): T {
const after: any = {}
for (const field in this.table) {
const { default: def, validate } = this.table[field]
for (const field in this.scheme) {
const { default: def, validate } = this.scheme[field]
const v = record[field] ?? def()
if (validate && !validate(v)) {
throw new Error(`The value '${v}' did not pass the validation of field '${field}'.`)
Expand All @@ -413,13 +413,13 @@ export class TissueRollDocument<T extends TissueRollDocumentRecordShape> {
get metadata() {
const { autoIncrement, count } = this._metadata
const { payloadSize, timestamp } = this.db.metadata
const { tableVersion } = this
const { schemeVersion } = this
return {
autoIncrement,
count,
payloadSize,
timestamp,
tableVersion
schemeVersion
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const createDocumentDatabase = (name: string) => {
version: 0,
payloadSize: 1024,
overwrite: true,
table: {
scheme: {
name: {
default: () => '',
validate: (v) => typeof v === 'string'
Expand Down

0 comments on commit 5c2d5f7

Please sign in to comment.