diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index daf9c0c..59660cd 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -1,4 +1,4 @@
-# For most projects, this workflow file will not need changing; you simply need
+# For most projects, this workflow file will not need changing you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
diff --git a/README.md b/README.md
index c561144..d9517fa 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,20 @@
![](https://raw.githubusercontent.com/Tarasikee/tinydb/v1.0.0-alpha/images/Logo1.png)
-
# TinyDB
Tiny, Powerful, Beautiful
## Contents:
-
- [Motivation](#motivation)
- [Let's start](#lets-start)
# Motivation
-
Let's say you want to build a small project that doesn't require a bulky relational database such as Postgres or MySQL. Instead, you want to use a simple, in-memory database that will cover your needs.
-That's where TykeDB comes in. TykeDB is a tiny, simple, and fast in-memory database that you can use to store and retrieve data. It has all the features of a relational database, but it designed to be as lightweight and simple as possible.
+That's where TinyDB comes in. TinyDB is a tiny, simple, and fast in-memory database that you can use to store and retrieve data. It has all the features of a relational database, but it designed to be as lightweight and simple as possible.
No need to install software or to set up a server. You're ready to go after installing dependencies.
# Let's start
-
-Your entry point is ```@TinyTable``` decorator, where you pass tyke's name.
+Your entry point is ```@TinyTable``` decorator, where you pass table's name.
There are tons of decorators you can use to customize your database. In the example below, you can see ```@Column``` decorators.
@@ -29,20 +25,20 @@ class User {
type: "string",
unique: true,
})
- name!: string;
+ name!: string
@Column({
type: "date",
allowNull: true,
})
- birthday!: string;
+ birthday!: string
@Column({
type: "boolean",
default: false,
allowNull: true,
})
- isAdmin!: boolean;
+ isAdmin!: boolean
@Column({
allowNull: true,
@@ -52,14 +48,14 @@ class User {
lang: 'en',
}
})
- settings!: Record;
+ settings!: Record
@Column({
type: "array",
allowNull: true,
default: [],
})
- friends!: string[];
+ friends!: string[]
}
```
diff --git a/deps/deps.ts b/deps/deps.ts
index 29f84e2..ea1d693 100644
--- a/deps/deps.ts
+++ b/deps/deps.ts
@@ -1,2 +1,2 @@
-export {parse} from "https://deno.land/std@0.144.0/datetime/mod.ts";
-export { ensureDirSync } from "https://deno.land/std@0.78.0/fs/mod.ts";
\ No newline at end of file
+export {parse} from "https://deno.land/std@0.144.0/datetime/mod.ts"
+export { ensureDirSync } from "https://deno.land/std@0.78.0/fs/mod.ts"
\ No newline at end of file
diff --git a/src/classes/Instance.ts b/src/classes/Instance.ts
index 15d6c6c..81ec04e 100644
--- a/src/classes/Instance.ts
+++ b/src/classes/Instance.ts
@@ -1,7 +1,7 @@
import {ColumnsUtils, FileUtils, Schema} from "../mod.ts"
interface InstanceOptions {
- isNew: boolean;
+ isNew: boolean
}
export class Instance {
@@ -20,8 +20,8 @@ export class Instance {
public delete() {
const db = FileUtils.readJson("./database/db.json")
- const filteredTable = db[this._schema.name]
- .filter(row => row._id !== this._fields._id)
+ const filteredTable = db[this._schema.name].filter(row => row._id !== this._fields._id)
+
FileUtils.writeJson("./database/db.json", {
...db,
[this._schema.name]: filteredTable
diff --git a/src/classes/Model.ts b/src/classes/Model.ts
index 1fc7fbc..e4462d9 100644
--- a/src/classes/Model.ts
+++ b/src/classes/Model.ts
@@ -6,13 +6,22 @@ export class Model {
) {
}
+ private getTable(): T[] {
+ const db = FileUtils.readJson("./database/db.json")
+ return db[this.schema.name] ?? []
+ }
+
+
+ // Creators
+
public create(args: T) {
return new Instance(this.schema, args, {isNew: true})
}
+ // Finders
+
public findById(_id: string) {
- const db = FileUtils.readJson("./database/db.json")
- const table = db[this.schema.name] ?? []
+ const table = this.getTable()
const candidate = table.find(row => row._id === _id)
if (candidate === undefined) {
@@ -25,17 +34,12 @@ export class Model {
}
public find(args: Partial) {
- const db = FileUtils.readJson("./database/db.json")
- const table = db[this.schema.name] ?? []
+ const table = this.getTable()
const keys = Object.keys(args) as unknown as Array
- const filteredTable = table.filter(row =>
- keys.every(key =>
- ObjectUtils.nestedCheck(row, key, args[key])))
-
- return filteredTable.map(row => new Instance(this.schema, row, {
- isNew: false
- }))
+ return table
+ .filter(row => keys.every(key => ObjectUtils.nestedCheck(row, key, args[key])))
+ .map(row => new Instance(this.schema, row, {isNew: false}))
}
public findOne(args: Partial) {
@@ -43,9 +47,24 @@ export class Model {
}
public findAll() {
- const db = FileUtils.readJson("./database/db.json")
- return db[this.schema.name].map(row => new Instance(this.schema, row, {
- isNew: false
- }))
+ return this
+ .getTable()
+ .map(row => new Instance(this.schema, row, {isNew: false}))
+ }
+
+ // Hunters
+ public hunt(args: Partial) {
+ this.find(args).map(instance => instance.delete())
+ return "Successful hunt!"
+ }
+
+ public huntOne(args: Partial) {
+ this.findOne(args).delete()
+ return "Successful single hunt!"
+ }
+
+ public huntAll() {
+ this.findAll().map(instance => instance.delete())
+ return "Successful absolute hunt!"
}
}
diff --git a/src/classes/Table.ts b/src/classes/Table.ts
index f4152eb..885f42e 100644
--- a/src/classes/Table.ts
+++ b/src/classes/Table.ts
@@ -1,28 +1,28 @@
-import {FileUtils} from "../mod.ts";
+import {FileUtils} from "../mod.ts"
export class Table {
public static init(name: string) {
try {
- const isExists = FileUtils.isFileExists("./database/db.json");
+ const isExists = FileUtils.isFileExists("./database/db.json")
if (isExists) {
- return this;
+ return this
}
- FileUtils.createOrCheckDir("./database");
- FileUtils.writeJson("./database/db.json", {[name]: []});
- return this;
+ FileUtils.createOrCheckDir("./database")
+ FileUtils.writeJson("./database/db.json", {[name]: []})
+ return this
} catch (e) {
- console.error(e.message);
+ console.error(e.message)
}
}
public static nuke(name: string) {
try {
- FileUtils.writeJson("./database/db.json", {[name]: []});
- return 'Nuke\'em';
+ FileUtils.writeJson("./database/db.json", {[name]: []})
+ return 'Nuke\'em'
} catch (e) {
- console.error(e.message);
+ console.error(e.message)
}
}
}
diff --git a/src/classes/mod.ts b/src/classes/mod.ts
index 0ba4547..24d854e 100644
--- a/src/classes/mod.ts
+++ b/src/classes/mod.ts
@@ -1,5 +1,5 @@
-export {Instance} from "./Instance.ts";
-export {Model} from "./Model.ts";
-export {Schema} from "./Schema.ts";
-export {Table} from "./Table.ts";
+export {Instance} from "./Instance.ts"
+export {Model} from "./Model.ts"
+export {Schema} from "./Schema.ts"
+export {Table} from "./Table.ts"
diff --git a/src/decorators/Column.ts b/src/decorators/Column.ts
index bb30b19..189de31 100644
--- a/src/decorators/Column.ts
+++ b/src/decorators/Column.ts
@@ -1,16 +1,16 @@
-import {Reflect} from "https://deno.land/x/reflect_metadata@v0.1.12/mod.ts";
-import {ColumnProps} from "../interfaces/Column.ts";
+import {Reflect} from "https://deno.land/x/reflect_metadata@v0.1.12/mod.ts"
+import {ColumnProps} from "../interfaces/Column.ts"
-const formatMetadataKey = Symbol("columns");
+const formatMetadataKey = Symbol("columns")
export function getFormat(target: unknown, propertyKey: string) {
- return Reflect.getMetadata(formatMetadataKey, target, propertyKey);
+ return Reflect.getMetadata(formatMetadataKey, target, propertyKey)
}
export function Column(options: ColumnProps) {
const optionsProxy = options.allowNull === undefined
? {...options, allowNull: false}
- : {...options, allowNull: true};
+ : {...options, allowNull: true}
- return Reflect.metadata(formatMetadataKey, optionsProxy);
+ return Reflect.metadata(formatMetadataKey, optionsProxy)
}
diff --git a/src/errors/ErrorWithHint.ts b/src/errors/ErrorWithHint.ts
index 7eda40c..b6acb15 100644
--- a/src/errors/ErrorWithHint.ts
+++ b/src/errors/ErrorWithHint.ts
@@ -3,6 +3,6 @@ export class ErrorWithHint extends Error {
super(`
Message: ${message}
Hint: ${hint}
- `);
+ `)
}
}
diff --git a/src/errors/mod.ts b/src/errors/mod.ts
index 5cdaa31..a177653 100644
--- a/src/errors/mod.ts
+++ b/src/errors/mod.ts
@@ -1 +1 @@
-export {ErrorWithHint} from "./ErrorWithHint.ts";
+export {ErrorWithHint} from "./ErrorWithHint.ts"
diff --git a/src/interfaces/Column.ts b/src/interfaces/Column.ts
index fecbe52..a2e527a 100644
--- a/src/interfaces/Column.ts
+++ b/src/interfaces/Column.ts
@@ -1,14 +1,14 @@
-export type OptionTypes = "string" | "number" | "boolean" | "date" | "json" | "array";
+export type OptionTypes = "string" | "number" | "boolean" | "date" | "json" | "array"
export interface ColumnProps {
- unique?: boolean;
- type?: OptionTypes;
- allowNull?: boolean;
+ unique?: boolean
+ type?: OptionTypes
+ allowNull?: boolean
// deno-lint-ignore no-explicit-any
- default?: any;
+ default?: any
}
export interface ColumnRules {
- name: string;
- options: ColumnProps;
+ name: string
+ options: ColumnProps
}
diff --git a/src/interfaces/Document.ts b/src/interfaces/Document.ts
index dd07af3..b2609d4 100644
--- a/src/interfaces/Document.ts
+++ b/src/interfaces/Document.ts
@@ -1,4 +1,4 @@
export interface Document {
- _id: string;
- _tableName: string;
+ _id: string
+ _tableName: string
}
diff --git a/src/mod.ts b/src/mod.ts
index e4b51c9..ad7d7bb 100644
--- a/src/mod.ts
+++ b/src/mod.ts
@@ -1,14 +1,14 @@
// Main classes
-export {Model, Instance, Schema, Table} from "./classes/mod.ts";
+export {Model, Instance, Schema, Table} from "./classes/mod.ts"
// Utils
-export {FileUtils, ObjectUtils, ColumnsUtils} from "./utils/mod.ts";
+export {FileUtils, ObjectUtils, ColumnsUtils} from "./utils/mod.ts"
// Decorators
-export {Column, getFormat, TinyTable} from "./decorators/mod.ts";
+export {Column, getFormat, TinyTable} from "./decorators/mod.ts"
// Types
-export type {OptionTypes, ColumnProps, ColumnRules, Document} from "./interfaces/mod.ts";
+export type {OptionTypes, ColumnProps, ColumnRules, Document} from "./interfaces/mod.ts"
// Errors
-export { ErrorWithHint } from "./errors/mod.ts";
\ No newline at end of file
+export { ErrorWithHint } from "./errors/mod.ts"
\ No newline at end of file
diff --git a/src/utils/ColumnsUtils.ts b/src/utils/ColumnsUtils.ts
index 2b8997e..9f00500 100644
--- a/src/utils/ColumnsUtils.ts
+++ b/src/utils/ColumnsUtils.ts
@@ -1,6 +1,6 @@
-import {ColumnRules, OptionTypes} from "../interfaces/mod.ts";
-import {ErrorWithHint} from "../errors/mod.ts";
-import {parse} from "../../deps/deps.ts";
+import {ColumnRules, OptionTypes} from "../interfaces/mod.ts"
+import {ErrorWithHint} from "../errors/mod.ts"
+import {parse} from "../../deps/deps.ts"
export class ColumnsUtils {
constructor(
@@ -8,70 +8,70 @@ export class ColumnsUtils {
private table: Array = [],
private record: T
) {
- this.run();
+ this.run()
}
private checkType(value: T[keyof T], columnName: string, checkType?: OptionTypes) {
- const valueType = typeof value;
+ const valueType = typeof value
if (checkType === "date") {
try {
- return parse(String(value), "yyyy-MM-dd");
+ return parse(String(value), "yyyy-MM-dd")
} catch (_) {
- throw new Error(`${columnName} must be data`);
+ throw new Error(`${columnName} must be data`)
}
}
if (checkType === "array") {
- if (!Array.isArray(value)) throw new Error(`${columnName} must be array`);
- return;
+ if (!Array.isArray(value)) throw new Error(`${columnName} must be array`)
+ return
}
if (checkType === "json") {
- if (typeof value === "object" && !Array.isArray(value) && value !== null) return;
- throw new Error(`${columnName} must be json`);
+ if (typeof value === "object" && !Array.isArray(value) && value !== null) return
+ throw new Error(`${columnName} must be json`)
}
if (valueType !== checkType) {
- throw new Error(`${columnName} must be ${checkType}`);
+ throw new Error(`${columnName} must be ${checkType}`)
}
}
private unique(column: ColumnRules) {
- const name = column.name as keyof T;
+ const name = column.name as keyof T
if (this.table.some(row => row[name] === this.record[name])) {
throw new ErrorWithHint(
`${String(name)} must be unique`,
`${this.record[name]} is already exists`
- );
+ )
}
}
private type(column: ColumnRules) {
- const name = column.name as keyof T;
- const value = this.record[name];
- return this.checkType(value, String(name), column.options.type);
+ const name = column.name as keyof T
+ const value = this.record[name]
+ return this.checkType(value, String(name), column.options.type)
}
private default(column: ColumnRules) {
- const name = column.name as keyof T;
- this.record[name] = column.options.default;
+ const name = column.name as keyof T
+ this.record[name] = column.options.default
}
private run() {
this.columnRules.map(rule => {
if (rule.options.allowNull &&
this.record[rule.name as keyof T] === undefined &&
- rule.options.default === undefined) return;
+ rule.options.default === undefined) return
if (
rule.options.default !== undefined &&
- this.record[rule.name as keyof T] === undefined) this.default(rule);
+ this.record[rule.name as keyof T] === undefined) this.default(rule)
- rule.options.type !== undefined && this.type(rule);
- rule.options.unique !== undefined && this.unique(rule);
- });
+ rule.options.type !== undefined && this.type(rule)
+ rule.options.unique !== undefined && this.unique(rule)
+ })
}
}
diff --git a/src/utils/FileUtils.ts b/src/utils/FileUtils.ts
index 8210b15..32d8328 100644
--- a/src/utils/FileUtils.ts
+++ b/src/utils/FileUtils.ts
@@ -3,38 +3,38 @@ import { ensureDirSync } from "../../deps/deps.ts"
export class FileUtils {
static writeJson(path: string, data: Record | Array): string {
try {
- Deno.writeTextFileSync(path, JSON.stringify(data));
- return "Written to " + path;
+ Deno.writeTextFileSync(path, JSON.stringify(data))
+ return "Written to " + path
} catch (e) {
- return e.message;
+ return e.message
}
}
static isFileExists(path: string): boolean {
try {
- Deno.statSync(path);
- return true;
+ Deno.statSync(path)
+ return true
} catch (e) {
console.log(e.message)
- return false;
+ return false
}
}
static createOrCheckDir(path: string): string {
try {
- ensureDirSync(path);
- return "Created directory " + path;
+ ensureDirSync(path)
+ return "Created directory " + path
} catch (e) {
- return e.message;
+ return e.message
}
}
static readJson(path: string): Record> {
try {
- const data = Deno.readTextFileSync(path);
- return JSON.parse(data);
+ const data = Deno.readTextFileSync(path)
+ return JSON.parse(data)
} catch (_e) {
- return {};
+ return {}
}
}
}
diff --git a/src/utils/ObjectUtils.ts b/src/utils/ObjectUtils.ts
index 85d3161..545b8d0 100644
--- a/src/utils/ObjectUtils.ts
+++ b/src/utils/ObjectUtils.ts
@@ -2,6 +2,7 @@ export class ObjectUtils {
// deno-lint-ignore no-explicit-any
static nestedCheck>(obj: T, key: keyof T, value: any): boolean {
+ // TODO: changeeeeeees
if (typeof obj[key] === "boolean" && typeof value === "boolean") {
return obj[key] === value
}