Skip to content
This repository has been archived by the owner on Aug 12, 2024. It is now read-only.

Commit

Permalink
Merge pull request #23 from rwl-dev/rename-file-format
Browse files Browse the repository at this point in the history
Renamed file storage format
  • Loading branch information
windchime-yk authored Dec 21, 2022
2 parents ac8972a + 1f5ca8f commit 6ae668c
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 120 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Setup Deno
uses: denolib/setup-deno@v2
uses: denoland/setup-deno@v1
with:
deno-version: v1.x
- name: Test
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"deno.enable": true
"deno.enable": true,
"deno.inlayHints.parameterNames.enabled": "none"
}
45 changes: 29 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,52 @@ DB module in JSON format created with Deno.
- The storage formats are in-memory and file

## Upcoming features
- [x] Write data
- [x] Delete the specified data
- [x] Return data that matches the condition
- [x] Save the data as a file
- [x] Asynchronous support
- [x] Partial search with regular expressions
Support for Local Storage API and Cache API is planned.
See [Issues](https://github.com/rwl-dev/bracesdb/issues) for more information.

If you don't see a feature you think you need, please let us know what you want in [Issue](https://github.com/rwl-dev/bracesdb/issues/new). It will be used as a reference for implementation.
If you don't see a feature you think you need, please [create an Issue](https://github.com/rwl-dev/bracesdb/issues/new) and let me know. You will use it as a reference.

## API
When creating a file, you must add `--allow-read` and `--allow-write` at execution to read and write the file.
There are two main types: file creation and in-memory.
The file creation format has a separate module as `FileDB`, because Deno Deploy cannot create files due to its specification. The others are modularized as `BracesDB`.
Since `FileDB` reads and writes files, please add `--allow-read` and `--allow-write` when executing.

### Create DB
`type` is the DB type. If it is "file", it is a file; if it is "memory", it is managed in-memory.
### BracesDB
#### Create DB
`type` is the DB type. Currently, only in-memory can be specified.

``` typescript
import { BracesDB } from "https://deno.land/x/bracesdb/mod.ts";

interface DB {
name?: string;
description?: string;
}

const db = new BracesDB<DB>({ type: "memory" });
```

### FileDB
#### Create DB
`folder` is the DB path. Default path is project root.
`filename` is the DB name. Default name is `main`.

``` typescript
import { BracesDB } from "https://deno.land/x/bracesdb@<version>/mod.ts";
import { BracesDB } from "https://deno.land/x/bracesdb/mod.ts";

interface DB {
name?: string;
description?: string;
}

const db = new BracesDB<DB>({
type: "file",
folder: "./db/",
filename: "test",
});
```

### Add an Object to the DB
### Common processing
#### Add an Object to the DB
The first argument is the Object to add to the DB.
The second argument is the key used in the duplication prevention process.
``` typescript
Expand All @@ -58,13 +71,13 @@ const test = {
await db.add(test, "name");
```

### Remove matching objects from DB
#### Remove matching objects from DB
The first argument is the key, and the second argument is the value of the key.
``` typescript
await db.delete("name", "Toika Asomaka");
```

### Searching the DB
#### Searching the DB
Perfect match and partial match supported.
Returns an Object that matches the conditions, with the name of the key as the first argument and the value of the key as the second argument.
No arguments return all DB data.
Expand All @@ -81,7 +94,7 @@ const dataAll = db.find();
Execute the following command.
``` bash
$ git clone https://github.com/rwl-dev/bracesdb.git
$ cd path/to/bracesdb
$ cd bracesdb

$ deno task test
```
Expand Down
48 changes: 31 additions & 17 deletions README_JP.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,52 @@ Denoで作られたJSON形式のDBモジュール。
- インメモリとファイルでのデータ保存に対応

## 今後追加される機能
- [x] データを書き込み
- [x] 指定したデータを削除
- [x] 条件に合致するデータを返す
- [x] データをファイルとして保存
- [x] 非同期対応
- [x] 正規表現による部分検索
Local Storage APIやCache APIへの対応を予定しています。
詳細は[Issues](https://github.com/rwl-dev/bracesdb/issues)を参照してください。

もし必要だと思う機能がなければ、[Issues](https://github.com/rwl-dev/bracesdb/issues/new)で教えてください。参考にします。
もし必要だと思う機能がなければ、[Issueを作成して](https://github.com/rwl-dev/bracesdb/issues/new)教えてください。参考にします。

## API
ファイルを作成する保存形式では、ファイルの読み込みと書き込みを行なうため、実行の際に`--allow-read``--allow-write`をつけてください。
大きく分けてファイル作成形式とインメモリ形式があります。
ファイル作成形式は`FileDB`としてモジュールが分離されており、これはDeno Deployが仕様上ファイル作成できないためです。それ以外は`BracesDB`としてモジュール化されています。
`FileDB`ではファイルの読み込みと書き込みを行なうため、実行の際に`--allow-read``--allow-write`をつけてください。

### DBの作成
`type`はDBの種類です。`file`ならファイル、`memory`ならインメモリで管理します。
### BracesDB
#### DBの作成
`type`はDBの種類です。現在はインメモリのみ指定できます。

``` typescript
import { BracesDB } from "https://deno.land/x/bracesdb/mod.ts";

interface DB {
name?: string;
description?: string;
}

const db = new BracesDB<DB>({ type: "memory" });
```

### FileDB
#### DBの作成
`folder`はDBファイルを格納するフォルダのパスです。デフォルトではプロジェクトルートに生成されます。
`filename`はDBファイルの名前です。デフォルトは`main`です。

``` typescript
import { BracesDB } from "https://deno.land/x/bracesdb@<version>/mod.ts";
import { FileDB } from "https://deno.land/x/bracesdb/mod.ts";

interface DB {
name?: string;
description?: string;
}

const db = new BracesDB<DB>({
type: "file",
const db = new FileDB<DB>({
folder: "./db/",
filename: "test",
});
```

### データの追加
### 共通処理
#### データの追加
第1引数はDBに追加するObject、第2引数は重複防止処理で利用するkeyです。
以下の例の場合、`name`の値が重複すると追加されません。なお、現状は無警告で重複を弾きます。
``` typescript
Expand All @@ -57,14 +71,14 @@ const test = {
await db.add(test, "name");
```

### データの削除
#### データの削除
DBから該当するObjectを削除します。
第1引数はkey、第2引数はその値です。
``` typescript
await db.delete("name", "あそまか といか");
```

### データの検索
#### データの検索
完全一致と正規表現による部分一致に対応しています。
第1引数にkeyの名前、第2引数にkeyの値を指定し、該当するObjectを返します。
引数なしは、DBデータすべてを返します。
Expand All @@ -81,7 +95,7 @@ const dataAll = db.find();
以下のコマンドを実行してください。
``` bash
$ git clone https://github.com/rwl-dev/bracesdb.git
$ cd path/to/bracesdb
$ cd bracesdb

$ deno task test
```
24 changes: 24 additions & 0 deletions core/memory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { DatabaseFormat } from "../model.ts";

export const memoryFormat: DatabaseFormat = {
add<T>(data: T[], object: T, keyword: keyof T) {
const isDuplicate =
data?.filter((item) => item[keyword] === object[keyword]).length;
if (isDuplicate) return data;

data?.push(object);
return data;
},

delete<T>(data: T[], key: keyof T, keyword: T[keyof T]) {
return data?.filter((item) => item[key] !== keyword);
},

find<T>(data: T[], key?: keyof T, keyword?: T[keyof T] | RegExp) {
if (key && keyword instanceof RegExp) {
return data?.filter((item) => keyword.test(`${item[key]}`));
} else if (key && keyword) {
return data?.filter((item) => item[key] === keyword);
} else return data;
},
};
26 changes: 26 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions deps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export {
isExistFileSync,
readFileSync,
writeFile,
writeFileSync,
} from "https://pax.deno.dev/windchime-yk/[email protected]/file.ts";

export { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
64 changes: 64 additions & 0 deletions filedb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {
isExistFileSync,
readFileSync,
writeFile,
writeFileSync,
} from "./deps.ts";
import { memoryFormat } from "./core/memory.ts";
import type { FileDBOption } from "./model.ts";

export class FileDB<T> {
private readonly folder?: string;
private readonly file: string;
private data: T[];

constructor(option: FileDBOption) {
const { folder = "./", filename = "main" } = option;

this.folder = folder;
this.file = `${folder}${
folder?.slice(-1) === "/" ? "" : "/"
}${filename}.db`;
this.data = [];

if (this.folder && !isExistFileSync(this.folder)) {
Deno.mkdirSync(this.folder, { recursive: true });
}
if (this.folder && !isExistFileSync(this.file)) {
writeFileSync(JSON.stringify(this.data), this.file);
}
if (isExistFileSync(this.file)) {
const json: T[] = JSON.parse(readFileSync(this.file));
this.data = json;
}
}

/**
* Add an Object to the DB
* @param object Object to be added to the DB
* @param keyword Use the specified key to prevent duplication
*/
async add(object: T, keyword: keyof T) {
this.data = memoryFormat.add(this.data, object, keyword);
await writeFile(JSON.stringify(this.data), this.file);
}

/**
* Remove matching objects from DB
* @param key The key of the Object you want to search
* @param keyword Wording of search conditions
*/
async delete(key: keyof T, keyword: T[keyof T]) {
this.data = memoryFormat.delete(this.data, key, keyword);
await writeFile(JSON.stringify(this.data), this.file);
}

/**
* Searching the DB
* @param key The key of the Object you want to search
* @param keyword Wording of search conditions
*/
find(key?: keyof T, keyword?: T[keyof T] | RegExp) {
return memoryFormat.find(this.data, key, keyword);
}
}
Loading

0 comments on commit 6ae668c

Please sign in to comment.