Skip to content

Commit

Permalink
Change: pre-release 0.0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
jswildcards committed Oct 26, 2020
1 parent 7bb1e97 commit 3162cdb
Show file tree
Hide file tree
Showing 14 changed files with 292 additions and 124 deletions.
10 changes: 6 additions & 4 deletions .eggignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
.git/
.github/
.vscode/
.eggignore
.git
.github
.gitignore
.vscode
CHANGELOG.md
CODE_OF_CONDUCT.md
LICENSE
CONTRIBUTING.md
egg.yml
LICENSE
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.0.5] - 2020-10-26
### Added
- CHANGELOG to log the changes between versions like other standardied open source projects.
- README add badges.
- fs to manage database file system.
- dataset to manage the operations on retrieved data from database.
- sort_and_select example to demonstrate dataset operation.
### Changed
- test cases
- documentations
- now we can use filter functions to select data from database
2 changes: 1 addition & 1 deletion egg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ files:
- ./deps.ts
- ./src/**/*
- ./mod.ts
version: 0.0.4
version: 0.0.5
checkAll: true
unlisted: false
66 changes: 66 additions & 0 deletions example/sort_and_select.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Document, FileDB } from "../mod.ts";

interface User extends Document {
username?: string;
favourites?: string[];
}

const db = new FileDB();
const users = await db.getCollection<User>("users");

const compareFavourites = (a: User, b: User) => {
const numberMoreThan = (a.favourites?.length ?? 0) -
(b.favourites?.length ?? 0);
return numberMoreThan / Math.abs(numberMoreThan || 1);
};

const compareUsername = (a: User, b: User) => {
const aName = a.username ?? "";
const bName = b.username ?? "";
return aName > bName ? 1 : (aName < bName ? -1 : 0);
};

users.insertMany([
{
username: "foo",
favourites: ["🍎 Apple", "🍐 Pear"],
},
{
username: "baz",
favourites: ["🍌 Banana"],
},
{
username: "bar",
favourites: ["🍌 Banana"],
},
]);

// Test 1: Sort by number of favourites
const value1 = users.find({}).sort(compareFavourites).select(["username"])
.value();

console.log(value1); // "baz", "bar", "foo"

// Test 2: First sort by number of favourites, then sort by username
const value2 = users.find({}).sort((a, b) => {
const compareResult = compareFavourites(a, b);
if (compareResult) {
return compareResult;
}
return compareUsername(a, b);
}).select(["username"]).value();

console.log(value2); // "bar", "baz", "foo"

// Test 3: First sort by number of favourites in DECENDING order, then sort by username
const value3 = users.find({}).sort((a, b) => {
const compareResult = -compareFavourites(a, b);
if (compareResult) {
return compareResult;
}
return compareUsername(a, b);
}).select(["username"]).value();

console.log(value3); // "foo", "bar", "baz"

db.drop();
2 changes: 1 addition & 1 deletion mod.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from "./src/db.ts";
export * from "./src/collection.ts";
export * from "./src/types.ts";
export * from "./src/fs.ts";
export * from "./src/fsmanager.ts";
export * from "./src/dataset.ts";
51 changes: 28 additions & 23 deletions src/collection.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,40 @@
import { uuid } from "../deps.ts";
import { Document, Selector } from "./types.ts";
import { DBFileSystem } from "./fs.ts";
import { FileSystemManager } from "./fsmanager.ts";
import { Dataset } from "./dataset.ts";

/**
* A Collection to store data
* A collection to store data
* @property {string} name - collection name
* @property {T[]} data - the collection data stored
* @property {FileSystemManager} fsManager - the file system manager of database
*/
export class Collection<T extends Document> {
private name = "";
private data: T[] = [];
private fs: DBFileSystem;
private fsManager: FileSystemManager;

/**
* Ensure the collection file is existed. Read the initial
* data from the file if the file existed.
*
* @constructor
* @param name the Collection name
* @param {string} name - the Collection name
*/
constructor(name: string, fs: DBFileSystem) {
constructor(name: string, fsManager: FileSystemManager) {
this.name = name;
this.fs = fs;
this.fsManager = fsManager;
}

async init() {
await this.fs.register(this.name);
this.data = JSON.parse(await this.fs.read(this.name) || "[]");
return this.fs.write(this.name, this.data);
await this.fsManager.register(this.name);
this.data = JSON.parse(await this.fsManager.read(this.name) || "[]");
return this.fsManager.write(this.name, this.data);
}

/**
* Find some documents by using filter conditions
*
* Caution! The method on this stage is only able to
* find documents with equals properties. For more options
* like greater than, less than or equal to, please wait
* for newer version
*
* @param selector filter conditions
* @return the filtered documents
*/
Expand All @@ -51,7 +49,11 @@ export class Collection<T extends Document> {
});
}));
}

/**
* Find one document by using filter conditions
* @param selector filter conditions
* @return the filtered document
*/
findOne(selector: Selector<T>) {
return this.find(selector)?.value()?.[0];
}
Expand Down Expand Up @@ -121,8 +123,8 @@ export class Collection<T extends Document> {
/**
* Bulk Update
*
* @param selector filter condition of documents
* @param document the updated document attributes
* @param {Selector<T>} selector - filter condition of documents
* @param {T} document - the updated document attributes
* @return the updated documents
*/
async updateMany(selector: Selector<T>, document: T) {
Expand All @@ -138,8 +140,8 @@ export class Collection<T extends Document> {
/**
* Delete a document
*
* @param selector Filter conditions of documents
* @return the deleted document ID
* @param {Selector<T>} selector Filter conditions of documents
* @return {string} the deleted document ID
*/
async deleteOne(selector: Selector<T>) {
const document = this.findOne(selector);
Expand All @@ -152,8 +154,8 @@ export class Collection<T extends Document> {
/**
* Bulk delete
*
* @param selector Filter conditions of documents
* @return the deleted document IDs
* @param {Selector<T>} selector - Filter conditions of documents
* @return {string[]} the deleted document IDs
*/
async deleteMany(selector: Selector<T>) {
const documents = this.find(selector).value();
Expand All @@ -167,11 +169,14 @@ export class Collection<T extends Document> {
* Save a copy of the data snapshot at this point to the file.
*/
async save() {
return this.fs.write(this.name, this.data);
return this.fsManager.write(this.name, this.data);
}

/**
* Autosave data when inserting, updating and deleting data
*/
async autosave() {
return this.fs.autowrite(this.name, this.data).catch((err) =>
return this.fsManager.autowrite(this.name, this.data).catch((err) =>
Promise.resolve(err)
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/collection_test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { assertEquals, exists } from "../deps.ts";
import { Collection } from "./collection.ts";
import { DBFileSystem } from "./fs.ts";
import { FileSystemManager } from "./fsmanager.ts";
import { Document } from "./types.ts";

interface User extends Document {
username?: string;
favourites?: string[];
}

const collection = new Collection<User>("users", new DBFileSystem());
const collection = new Collection<User>("users", new FileSystemManager());
const path = "./db/users.json";

Deno.test("collection: init", async function () {
Expand Down
24 changes: 19 additions & 5 deletions src/dataset.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { CompareFn } from "./types.ts";

export class Dataset<T> {
private originalData: T[];
private newData: T[];
private isChainFinished: boolean = false;
private isChainFinished = false;

constructor(data: T[]) {
this.originalData = [...data];
Expand All @@ -19,20 +21,32 @@ export class Dataset<T> {
return data;
}

/**
* Select which fields to retrieves
* @param {(keyof T)[]} fields - field keys to retrieves
*/
select(fields: (keyof T)[]) {
let data = this.retrieveData();
const data = this.retrieveData();
this.newData = data.map((el) =>
fields.reduce((obj, key) => ({ ...obj, [key]: el[key] }), {})
) as T[];
return this;
}

sort(fn: ((a: T, b: T) => number)) {
let data = this.retrieveData();
this.newData = data.sort(fn);
/**
* Sort the dataset
* @param {CompareFn<T>} compareFn - compare function tell how to sort
*/
sort(compareFn: CompareFn<T>) {
const data = this.retrieveData();
this.newData = data.sort(compareFn);
return this;
}

/**
* get the sorted and selected fields dataset
* @return {T[]} required dataset
*/
value() {
this.isChainFinished = true;
return this.newData;
Expand Down
12 changes: 12 additions & 0 deletions src/dataset_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,15 @@ Deno.test("dataset: 2", function () {
[{ username: "bar" }, { username: "baz" }, { username: "foo" }],
);
});

Deno.test("dataset: 3", function () {
const value = dataset.sort((a, b) =>
a.favourites.length < b.favourites.length
? 1
: (a.username > b.username ? 1 : -1)
).select(["username"]).value();
assertEquals(
value,
[{ username: "foo" }, { username: "bar" }, { username: "baz" }],
);
});
27 changes: 14 additions & 13 deletions src/db.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import { Collection } from "./collection.ts";
import { Document, FileDBOptions } from "./types.ts";
import { DBFileSystem } from "./fs.ts";
import { FileSystemManager } from "./fsmanager.ts";

/**
* The Database
* @class
* @property {Record<string, Collection<any>>} collections - collections of database
* @property {FileSystemManager} fsManager - the file system manager of database
*/
export class FileDB {
private collections: Record<string, Collection<any>> = {};
private fs: DBFileSystem;
private fsManager: FileSystemManager;

/**
* Ensure the data folder is existed.
*
* @constructor
* @param rootDir Optional: the base url of the data folder, default "./db"
* @param {FileDBOptions} dbOptions database options
*/
constructor(dbOptions?: FileDBOptions) {
this.fs = new DBFileSystem(dbOptions);
this.fsManager = new FileSystemManager(dbOptions);
}

/**
* Get a collection
*
* @param collectionName Collection Name
* @template T a type extending Collection Model
* @param {string} collectionName - Collection Name
* @template T - a type extending Collection Model
* @return the specified collection
*/
async getCollection<T extends Document>(collectionName: string) {
Expand All @@ -32,7 +33,7 @@ export class FileDB {
if (!isCollectionExist) {
this.collections[collectionName] = new Collection<T>(
collectionName,
this.fs,
this.fsManager,
);
await this.collections[collectionName].init();
}
Expand All @@ -59,11 +60,11 @@ export class FileDB {
}

/**
* Drop a database with the given path
* @param rootDir root directory of the database
* Drop the database
* @param {boolean} silence - silently drop without console.log even cannot find the database
*/
async drop(silence: boolean = false) {
return this.fs.deregister().catch((err) => {
async drop(silence = false) {
return this.fsManager.deregister().catch((err) => {
if (!silence) {
console.error(err);
}
Expand Down
Loading

0 comments on commit 3162cdb

Please sign in to comment.