🚧 Work in progress...
⭕ 0db
Simple JSON file based database with easy querying interface and common utilities.
For whatever reason, If you don't want to use a real database, and instead simply use a file. but also want some query and utility functions of a database. this is 0db 😁.
👇 Glimpse example :
db("users").create({ name: "kenza", email: "kenza@old.com" });
db("users").read({ name: "kenza" });
db("users").update({ name: "kenza" }, { email: "kenza@new.com" });
db("users").delete({ name: "kenza" });
0db is constituted of four (create
, read
, update
, and delete
) methods that represents the CRUD operations and three (or less) parameters (item
, query
, and options
) considerably (more or less) recurring in the four methods.
📥 Installation
npm i 0db
🏁 Getting Started
👇 Learn by a simple common example :
const $0db = require("0db");
const db = await $0db();
const createdUser = await db("users").create(
{
name: "kenza",
email: "kenza@email.com",
password: "secret123",
},
{
encrypt: "password",
}
);
const users = await db("users").read(
{ name: "kenza" },
{
omit: ["password", "email"],
}
);
const updatedUser = await db("users").update(
{ name: "kenza" },
{
email: "kenza@NewEmail.com",
password: "NEW_SECRET_123456789",
}
);
const deletedUser = await db("users").update({ email: "kenza@NewEmail.com" });
💡 A JSON file named db.json
(by default) is created in the root directory. This is an example of its content :
{
"users": [
{
"name": "kenza",
"email": "kenza@example.com",
"$id": "8c8f128e-4905-4e77-b664-e03f6de5e952",
"$createdAt": "2021-09-05T21:40:27Z"
},
{
"name": "ambratolm",
"email": "ambratolm@example.com",
"$id": "5211133c-a183-4c99-90ab-f857adf5442a",
"$createdAt": "2002-11-01T22:12:55Z",
"$updatedAt": "2021-10-02T00:00:00Z"
}
]
}
💡 Note that the $id
and $createdAt
fields are created automatically when an item is created, and $updatedAt
when it is updated.
🚩 Initialize
const db = await fsdb();
const db = await fsdb("my-database-file.json");
const db = await fsdb(__dirname + "/my-database-file");
🔎 Query
Query parameter in Read
, Update
, and Delete
methods is an object or function that allows targeting specific items in collection.
{
fieldName: fieldValue,
fieldName: fieldValue,
...etc
}
Query object is an object of property values to match against collection items.
A comparison is performed between every item object property values in collection and the query object property values to determine if an item object contains equivalences.
The items containing the equivalences are returned.
Example:
const queryObj = {
firstName: "kenza",
age: 20,
rating: 5
};
const users = await db("users").read(queryObj);
(item, index?, collection?) => [Boolean]
Query function is a predicate called for every item when iterating over items of collection.
All items predicate returns truthy for are returned.
The predicate is invoked with three arguments :
value
: Required. The value of the current item.index
: Optional. The index of the current item in collection.collection
: Optional. The collection array-object the current item belongs to.
Example:
const queryFn = (user) => {
return user.name.startsWith("k") && user.age >= 20 && rating >= 5;
};
const users = await db("users").read(queryFn);
☑️ Options
{
optionName: optionValue,
optionName: optionValue,
...etc
}
Options parameter in all methods is an object that allows to apply additional stuff to the method's subject item or to the method's returned items result.
Every method can have specific options or common options depending on the context of the method.
Example :
const options = {
unique: ["name", "email"],
encrypt: "password",
omit: ["email", "password"],
nocase: true
};
const user = {
name: "moulay-elhassan",
email: "hasson@example.com",
password: "secret#hasson?1980"
}
const createdUser = await db("users").create(user, options);
💠 CREATE
await db(collectionName).create(item?, options?);
Creates a new item in a collection.
💡 If the specified collection doesn't exist it will be created automatically.
💡 If no item object is specified (omitted, null
, or undefined
), an empty item is created with no fields except the system fields (with names starting with $ sign).
💡 The created item is returned.
Parameter | Type | Default | Description |
---|
collectionName | String | | Targeted collection name |
item | Object | {} | Item to create |
options | Object | {} | CREATE options |
@returns | Object | | The created item |
@throws | Error | | If a unique field value is already used |
@throws | Error | | If a value to encrypt is not a string |
☑️ CREATE Options
Property | Type | Default | Description |
---|
unique | String or String[] | "" | Fields to declare as unique |
encrypt | String or String[] | "" | Fields to encrypt |
pick | String or String[] | "" | Fields to pick in returned items |
omit | String or String[] | "" | Fields to omit in returned items |
nocase | Boolean | false | If true ignores case in search |
💡 When fields are declared as unique
, a checking for duplicates is done before adding the item.
💡 If nocase
is true, letter case comparison will be ignored in search operations, like for example checking unique
values.
🎯 CREATE Examples
const createdPlayer = await db("players").create({
name: "ambratolm",
level: 99,
inventory: ["sword", "shield", "potion"],
});
const createdPlayer = await db("players").create(
{
name: "ambratolm",
level: 99,
inventory: ["sword", "shield", "potion"],
password: "this_is_a_secret",
},
{
unique: "name",
encrypt: "password",
omit: ["password", "level"],
nocase: true,
}
);
💠 READ
await db(collectionName).read(query?, options?);
Reads an existing item in a collection.
💡 If the specified collection doesn't exist it will be created automatically.
💡 If no query is specified (omitted, null
, or undefined
), the query defaults to empty query {}
which returns all items.
💡 The read items are returned.
Parameter | Type | Default | Description |
---|
collectionName | String | | Targeted collection name |
query | Object | {} | Query object or function |
options | Object | {} | READ options |
@returns | Array | | The read item |
@throws | Error | | If an encrypted field not matched |
☑️ READ Options
Property | Type | Default | Description |
---|
one | Boolean | false | Return only one result (Object) |
pick | String or String[] | [] | Fields to pick in returned items |
omit | String or String[] | [] | Fields to omit in returned items |
nocase | Boolean | false | Ignore case in search |
sort | String or String[] | "" | Fields to sort by returned items |
order | String or String[] | "asc" | Order of sorting of returned items |
encrypt | String or String[] | [] | Fields to encrypt |
limit | Number | MAX | Number of returned items |
page | Number | 0 | Index of pagination (with limit) |
expand | String | "" | Name of collection to expand to |
embed | String | "" | Name of collection to embed |
🎯 READ Examples
const players = await db("players").read();
const somePlayers = await db("players").read({ name: "ambratolm" });
const someOtherPlayers = await db("players").read(
(player) => player.level >= 90
);
const player = await db("players").read(
{ name: "AmBrAtOlM" },
{
nocase: true,
one: true,
}
);
💠 UPDATE
await db(collectionName).update(query?, changes?, options?);
Updates an existing item in a collection.
💡 If the specified collection doesn't exist it will be created automatically.
💡 If no query is specified (omitted, null
, or undefined
), no item is updated.
💡 If an empty query {}
is specified, all items are updated.
💡 If no changes are specified (omitted, null
, or undefined
), the changes default to empty changes {}
which only updates the $updatedAt
field in targeted items.
💡 The updated items are returned.
Parameter | Type | Default | Description |
---|
collectionName | String | | Targeted collection |
query | Object | {} | Query object or function |
changes | Object | {} | Changes to apply |
options | Object | {} | Additional options |
@returns | Array | | The updated item |
@throws | Error | | If Items matching query not found |
@throws | Error | | If a unique field value is already used |
@throws | Error | | If a value to encrypt is not a string |
☑️ UPDATE Options
Property | Type | Default | Description |
---|
total | Boolean | false | If true overrides all item fields |
one | Boolean | false | Return only one result (Object) |
unique | String or String[] | "" | Fields to declare as unique |
encrypt | String or String[] | [] | Fields to encrypt |
pick | String or String[] | [] | Fields to pick in returned items |
omit | String or String[] | [] | Fields to omit in returned items |
nocase | Boolean | false | Ignore case in search |
🎯 UPDATE Examples
const updatedPlayer = await db("players").update(
{ name: "ambratolm" },
{ name: "new name", level: 0 }
);
const updatedPlayer = await db("players").update(
{ name: "ambratolm" },
{ name: "new name", level: 0 },
{
}
);
💠 DELETE
await db(collectionName).delete(query?, options?);
Deletes an existing item in a collection.
💡 If the specified collection doesn't exist it will be created automatically.
💡 If no query is specified (omitted, null
, or undefined
), no item is deleted.
💡 If an empty query {}
is specified, all items are deleted.
💡 The deleted items are returned.
Parameter | Type | Default | Description |
---|
collectionName | String | | Targeted collection name |
query | Object | {} | Query object or function |
options | Object | {} | Additional options |
@returns | Object | | The deleted item |
@throws | Error | | If Items matching query not found |
☑️ DELETE Options
Property | Type | Default | Description |
---|
one | Boolean | false | Return only one result (Object) |
pick | String or String[] | [] | Fields to pick in returned items |
omit | String or String[] | [] | Fields to omit in returned items |
nocase | Boolean | false | Ignore case in search |
🎯 DELETE Examples
const deletedPlayer = await db("players").delete(
{ name: "ambratolm" }
);
const deletedPlayer = await db("players").delete(
{ name: "ambratolm" },
{
}
);
↘️ Other
await db.drop();
await db("players").drop();
await db("players").clear();
📃 License
MIT © Ambratolm