Database Operations
Writing, reading, updating, deleting, counting, indexing, reloading and compacting.
class Model extends BaseModel {
name: string = "";
yearBorn: number = 0;
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
ref: "a-database-name",
model: Model,
});
await db.insert([Model.new({ yearBorn: 11 })]);
await db.find({ filter: { yearBorn: 11 } });
await db.update({ filter: { yearBorn: 11 }, update: { $set: { yearBorn: 11 } } });
await db.upsert({
filter: { yearBorn: 11 },
update: { $set: { yearBorn: 5 }, $setOnInsert: Model.new({ yearBorn: 5 }) },
});
await db.count({ yearBorn: 11 });
await db.delete({ filter: { yearBorn: 11 }, multi: true });
await db.createIndex({fieldName: "name"});
await db.removeIndex("name");
await db.reload();
await db.compact();
await db.forcefulUnlock();
await db.stopAutoCompaction();
await db.resetAutoCompaction(9000);
Database.insert
Database.insert
argument type
return type
aliases
Array<Model>
Promise<{
docs: Array<Model>;
number: number;
}>
Database.create
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "alex"; // default is "alex"
yearBorn: number = 1992; // default is
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
await db.insert([
Model.new({
yearBorn: 1990
/* default name will be used */
}),
Model.new({
name: "john"
/* default yearBorn will be used */
}),
Model.new({
name: "john"
yearnBorn: 1980,
_id: "some-unique-id",
}),
]);
Return type
Method return a promise fulfilling with object that has the following properties:
docs
: Is an array of the inserted documents.number
: Is the number of the inserted documents.
Database.find
Database.find
argument type
return type
aliases
{
filter?: Query<Model>;
skip?: number;
limit?: number;
sort?: Sort<Model>;
}
Promise<
Array<Model>
>
Database.read
interface FindArgument<Model> {
filter?: Query<Model>; // optional
skip?: number; // optional
limit: number; // optional
sort: Sort<Model>; // optional
}
Where:
filter
is a query similar to the query language of MongoDB, it can accepts direct equality evaluation like{age: 11}
or a field level operator:{age: { $gt: 11 }}
or a top level operator:$or: [{ age: 11 }, { age: 12 }]
.
skip
andlimit
are both number, and basically self-explanatory.sort
is an object that its keys must be the same asModel
keys (or some of them), yet the value of those keys must be either1
(for ascending sorting) or-1
(for descending sorting).
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "";
yearBorn: number = 0;
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
/**
* Will find all documents that has year born
* as 1992 and named "alex"
*/
await db.find({
filter: {
// direct filtering
yearBorn: 11,
name: "alex",
},
});
/**
* Will find all documents that has year born
* less than 1990 (1989, 1988 ... etc)
*/
await db.find({
filter: {
// field level operator
yearBorn: { $lt: 1990 },
},
});
/**
* Will find all documents that has year born
* either 1991 or 1981
*/
await db.find({
filter: {
// top level operator
$or: [{ yearBorn: 1991 }, { yearBorn: 1981 }],
},
});
/**
* Will find all documents that has year born
* not greater than 1990 nor less than 1980
* and named alex
*/
await db.find({
filter: {
// top level operator
// with field level operator
$nor: [{ yearBorn: { $lt: 1980 } }, { yearBorn: { $gt: 1990 } }],
name: "alex",
},
});
You can also use the computed value when filtering (the beauty of object mapping).
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "";
yearBorn: number = 0;
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
/**
* Will find all documents that has
* the computed value "age" as 12
* and named "alex"
*/
await db.find({
filter: {
// direct filtering
age: 12,
name: "alex",
},
});
Return type
Method return a promise fulfilling with an array of the matched documents. If no documents matches then the array would be empty.
Database.update
Database.update
argument type
return type
aliases
{
filter: Query<Model>;
update: Update<Model>;
multi: boolean;
}
Promise<{
docs: Array<Model>;
number: number;
}>
non
interface FindArgument<Model> {
filter: Query<Model>;
update: Update<Model>;
multi: boolean; // optional, defaults to false
}
Where:
filter
is a query similar to the query language of MongoDB, it can accepts direct equality evaluation like{age: 11}
or a field level operator:{age: { $gt: 11 }}
or a top level operator:$or: [{ age: 11 }, { age: 12 }]
.
update
is an object of update operators and modifiers, similar to the update operators and modifiers of MonogDB.multi
is aboolean
, defaults to false, if true it will update all the matched documents, if it's false it will update only the first matched document.
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "";
yearBorn: number = 0;
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
await db.update({
filter: { age: 11 },
// increment yearBorn by 15
// and set name to "john"
update: { $inc: { yearBorn: 15 }, $set: { name: "john" } },
});
Return type
Method return a promise fulfilling with object that has the following properties:
docs
: Is an array of the update documents.number
: Is the number of the updated documents.
Database.upsert
Database.upsert
argument type
return type
aliases
{
filter: Query<Model>;
update: Upsert<Model>;
multi: boolean;
}
Promise<{
docs: Array<Model>;
number: number;
upsert:boolean
}>
non
interface FindArgument<Model> {
filter: Query<Model>;
update: Upsert<Model>;
multi: boolean; // optional, defaults to false
}
Where:
filter
is a query similar to the query language of MongoDB, it can accepts direct equality evaluation like{age: 11}
or a field level operator:{age: { $gt: 11 }}
or a top level operator:$or: [{ age: 11 }, { age: 12 }]
.
update
is an object of update operators and modifiers, similar to the update operators and modifiers of MonogDB. But with one required field ($setOnInsert
). This field value must the document to be inserted if no documents where found to be updates.multi
is aboolean
, defaults to false, if true it will update all the matched documents, if it's false it will update only the first matched document.
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "";
yearBorn: number = 0;
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
await db.upsert({
filter: { name: "alex" },
update: {
$set: { age: 5 },
$setOnInsert: Model.new({ age: 5, name: "alex" })
},
});
Return type
Method return a promise fulfilling with object that has the following properties:
docs
: Is an array of the inserted/updated documents.number
: Is the number of the inserted/updated documents.upsert:
is a boolean that should betrue
when an insertion actually occurred, and should befalse
if an update occurred.
Database.count
Database.count
argument type
return type
aliases
Query<Model>
Promise<number>
Database.number
For counting documents that meet a specified query. This method takes the Query<Model>
as an argument. It is similar to the query language of MongoDB, it can accepts direct equality evaluation like {age: 11}
or a field level operator: {age: { $gt: 11 }}
or a top level operator: $or: [{ age: 11 }, { age: 12 }]
.
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "";
yearBorn: number = 0;
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
/**
* Will count all documents that has year born
* as 1992 and named "alex"
*/
await db.count({
// direct filtering
yearBorn: 11,
name: "alex",
});
/**
* Will count all documents that has year born
* less than 1990 (1989, 1988 ... etc)
*/
await db.count({
// field level operator
yearBorn: { $lt: 1990 },
});
/**
* Will count all documents that has year born
* either 1991 or 1981
*/
await db.count({
// top level operator
$or: [{ yearBorn: 1991 }, { yearBorn: 1981 }],
});
/**
* Will count all documents that has year born
* not greater than 1990 nor less than 1980
* and named alex
*/
await db.count({
// top level operator
// with field level operator
$nor: [{ yearBorn: { $lt: 1980 } }, { yearBorn: { $gt: 1990 } }],
name: "alex",
});
Return type
Method return a promise fulfilling with a number, that is the number of the documents matching the given query.
Database.delete
Database.delete
argument type
return type
aliases
{
filter: Query<Model>;
multi: boolean;
}
Promise<{
docs: Array<Model>;
number: number;
}>
Database.remove
interface FindArgument<Model> {
filter: Query<Model>;
update: Upsert<Model>;
multi: boolean; // optional, defaults to false
}
Where:
filter
is a query similar to the query language of MongoDB, it can accepts direct equality evaluation like{age: 11}
or a field level operator:{age: { $gt: 11 }}
or a top level operator:$or: [{ age: 11 }, { age: 12 }]
.
multi
is aboolean
, defaults to false, if true it will update all the matched documents, if it's false it will update only the first matched document.
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "";
yearBorn: number = 0;
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
/**
* deletes ALL documents that has 11
* as the value of property "age"
*/
await db.delete({
filter: { age: 11 },
multi: true
});
Return type
Method return a promise fulfilling with object that has the following properties:
docs
: Is an array of the deleted documents.number
: Is the number of the deleted documents.
Database.createIndex
Database.createIndex
argument type
return type
aliases
{
fieldName: string;
unique?: boolean;
sparse?: boolean;
expireAfterSeconds?: number;
}
Promise<{
affectedIndex: string
}>
Database.ensureIndex
fieldName
(required): name of the field to index.unique
(optional, defaults tofalse
): enforce field uniqueness. Note that a unique index will raise an error if you try to index two documents for which the field is not defined.sparse
(optional, defaults tofalse
): don't index documents for which the field is not defined. Use this option along with "unique" if you want to accept multiple documents for which it is not defined.expireAfterSeconds
(number of seconds, optional): if set, the created index is a TTL (time to live) index, that will automatically remove documents when the system date becomes larger than the date on the indexed field plusexpireAfterSeconds
. Documents where the indexed field is not specified or not aDate
object are ignored.
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "alex"; // default is "alex"
yearBorn: number = 1992; // default is
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
await db.createIndex({
fieldName: "name",
unique: false,
sparse: false
});
Return type
Method return a promise fulfilling with object that has the following properties:
affectedIndex
: Is a string of the field name that the index created upon.
Database.removeIndex
Database.removeIndex
argument type
return type
aliases
string
Promise<{
affectedIndex: string
}>
non
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "alex"; // default is "alex"
yearBorn: number = 1992; // default is
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
await db.removeIndex("name");
Return type
Method return a promise fulfilling with object that has the following properties:
affectedIndex
: Is a string of the field name that the index created upon.
Database.reload
Database.reload
argument type
return type
aliases
non
Promise<void>
non
Reloading the persistence layer (e.g. the file) of the database, so any changes that were made external to the instance of the database will be loaded into this instance.
import { BaseModel, Database, FS_Persistence_Adapter } from "./src";
class Model extends BaseModel {
name: string = "";
yearBorn: number = 0;
}
// first instance
const db1 = new Database<Model>({
ref: "a-database-name",
model: Model,
persistence_adapter: FS_Persistence_Adapter
});
// second instance on the same ref
// using the same persistence adapter
const db2 = new Database<Model>({
ref: "a-database-name",
model: Model,
persistence_adapter: FS_Persistence_Adapter
});
await db1.insert([Model.new({name: "john", yearBorn: 1983})])
// db2 is not aware of the insertion occurred in db1
// although they are both using the same file
await db2.reload();
Database.forcefulUnlock
Database.forcefulUnlock
argument type
return type
aliases
non
Promise<void>
non
There's a locking mechanism implemented in the file system persistence adapter to prevent two instances from modifying the same file at once. So one of them has to wait for the other. However, it may occur that one of the instances would crash while modifying the file and the lock would still be there, so the other instance would have to wait forever for the file to be unlocked.
This is why this utility method is provided as a means of forcefully unlocking the file.
Database.compact
Database.compact
argument type
return type
aliases
non
Promise<void>
non
When persisting data (e.g. into a file), the data will be persisted by appending, this is to avoid re-writing of the whole file in case of removing or updating. This behavior might result in an increase in the persistence layer size (e.g. file size). That's why the database provides you with a function to compact the file size:
import { Database, FS_Persistence_Adapter } from "tydb";
const mydb = new Database({
ref: "a-database-name",
persistence_adapter: FS_Persistence_Adapter,
});
mydb.compact(); // returns a promise
Database.resetAutoCompaction
Database.resetAutoCompaction
argument type
return type
aliases
number
Promise<void>
non
Resetting (or starting) auto compaction at intervals of time.
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "alex"; // default is "alex"
yearBorn: number = 1992; // default is
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
});
await db.resetAutoCompaction(10000) // every 10 seconds
setTimeout(async ()=>{
// after 20 seconds, auto compaction
// will occur every 30 seconds
await db.resetAutoCompaction(30000)
},20000)
Database.stopAutoCompaction
Database.stopAutoCompaction
argument type
return type
aliases
non
Promise<void>
non
Stopping auto compaction.
import { BaseModel, Database } from "./src";
class Model extends BaseModel {
name: string = "alex"; // default is "alex"
yearBorn: number = 1992; // default is
get age() {
return new Date().getFullYear() - this.yearBorn;
}
}
const db = new Database<Model>({
// database configuration parameters ...
ref: "a-database-name",
model: Model,
autoCompaction: 900
});
await db.stopAutoCompaction();
Last updated
Was this helpful?