
Security News
Socket Releases Free Certified Patches for Critical vm2 Sandbox Escape
A critical vm2 sandbox escape can allow untrusted JavaScript to break isolation and execute commands on the host Node.js process.
persist is an ORM framework for node.js.
The following databases are currently supported:
var persist = require("persist");
var type = persist.type;
// define some model objects
Phone = persist.define("Phone", {
"number": type.STRING
});
Person = persist.define("Person", {
"name": type.STRING
}).hasMany(this.Phone);
persist.connect({
driver: 'sqlite3',
filename: 'test.db',
trace: true
}, function(err, connection) {
Person.using(connection).all(function(err, people) {
// people contains all the people
});
});
You can install using Node Package Manager (npm):
npm install persist
If the current working directory contains a file called database.json this file will be loaded upon requiring persist. The file should follow a format like this:
{
"default": "dev",
"dev": {
"driver": "sqlite3",
"filename": ":memory:"
},
"test": {
"driver": "sqlite3",
"filename": ":memory:"
},
"prod": {
"driver": "sqlite3",
"filename": "prod.db"
"sqlDir": "./prodSql",
"pooling": {
"name": "testPool",
"max": 2,
"min": 1,
"idleTimeoutMillis": 30000
}
}
}
"default" specifies which environment to load.
The environment to read from the database.json file. If not set will use the value of default from the database.json.
Example
persist.env = 'prod';
### persist.connect([options], callback)
Connects to a database.
Arguments
Example
persist.connect({
driver: 'sqlite3',
filename: 'test.db',
trace: true
}, function(err, connection) {
// connnection esablished
});
### persist.define(modelName, properties, [opts]): Model
Defines a model object for use in persist.
The primary key column does not need to be specified and will default to the name 'id' with the attributes dbColumnName='id', type='integer'. You can override the database name using dbColumnName or setting the primaryKey attribute on any column.
Arguments
Returns
A model class.
Example
Person = persist.define("Person", {
"name": type.STRING,
"createdDate": { type: type.DATETIME, defaultValue: function() { return self.testDate1 }, dbColumnName: 'new_date' },
"lastUpdated": { type: type.DATETIME }
})
### persist.defineAuto(modelName, dbConfig, callback): Model
Defines a model object for use in persist. Columns are defined by the program in this method. Uses an existing database connection to retrieve column data.
Arguments
Returns
A model class.
Example
persist.defineAuto("Person",{driver:dbDriver, db:self.connection.db},function(err,model){
Person = model.hasMany(Phone)
.on('beforeSave', function (obj) {
obj.lastUpdated = testDate;
})
.on('afterSave', function (obj) {
if (!obj.updateCount) obj.updateCount = 0;
obj.updateCount++;
});
});
### persist.setDefaultConnectOptions(options)
Sets the default connection options to be used on future connect calls. see database.json
Arguments
Example
persist.setDefaultConnectOptions({
driver: 'sqlite3',
filename: 'test.db',
trace: true});
### persist.shutdown([callback])
Shutdown persist. This is currently only required if you are using connection pooling. see generic-pool.
Arguments
Example
persist.shutdown(function() {
console.log('persist shutdown');
});
## Connection
### connection.chain(chainables, callback)
Chains multiple statements together in order and gets the results.
Arguments
Example
// array chaining
connection.chain([
person3.save,
Person.min('age'),
Person.max('age'),
phone3.delete,
person2.delete,
Person.orderBy('name').all,
Phone.orderBy('number').first,
Phone.count,
Phone.deleteAll,
Phone.all,
Person.getById(1),
persist.runSql('SELECT * FROM Person')
], function(err, results) {
// results[0] = person3
// results[1] = 21
// results[2] = 25
// results[3] = []
// results[4] = []
// results[5] = -- all people ordered by name
// results[6] = -- first phone ordered by number
// results[7] = 100
// results[8] = []
// results[9] = [] -- nobody left
// results[10] = -- the person with id 1
// results[11] = Results of select.
});
// mapped chaining
connection.chain({
minAge: Person.min('age'),
maxAge: Person.max('age')
}, function(err, results) {
// results.minAge = 21
// results.maxAge = 25
});
### connection.tx(callback)
Begins a transaction on the connection.
Arguments
Example
connection.tx(function(err, tx) {
person1.save(connection, function(err) {
tx.commit(function(err) {
// person1 saved and committed to database
});
});
});
### connection.runSql(sql, values, callback)
Runs a sql statement that does not return results (INSERT, UPDATE, etc).
Arguments
Example
connection.runSql("UPDATE people SET age = ?", [32], function(err, results) {
// people updated
});
### connection.runSqlAll(sql, values, callback)
Runs a sql statement that returns results (ie SELECT).
Arguments
Example
connection.runSqlAll("SELECT * FROM people WHERE age = ?", [32], function(err, people) {
// people contains all the people with age 32
});
### connection.runSqlEach(sql, values, callback, doneCallback)
Runs a sql statement that returns results (ie SELECT). This is different from runSqlAll in that it returns each row in a seperate callback.
Arguments
Example
connection.runSqlEach("SELECT * FROM people WHERE age = ?", [32], function(err, person) {
// a single person
}, function(err) {
// all done
});
### connection.runSqlFromFile(filename, values, callback)
### connection.runSqlAllFromFile(filename, values, callback)
### connection.runSqlEachFromFile(filename, values, callback, doneCallback)
Same as runSql, runSqlAll, runSqlEach except the first parameter is a filename of where to load the SQL from.
Example
connection.runSqlFromFile('report.sql', [32], function(err, person) {
// a single person
}, function(err) {
// all done
});
## Model
### Model.hasMany(AssociatedModel, [options]): Model
Adds a has many relationship to a model. This will automatically add a property to the associated model which links to this model. It will also define a property on instances of this model to get the releated objects - see Associated Object Properties
Arguments
Returns
The model class object suitable for chaining.
Example
Phone = persist.define("Phone", {
"number": persist.String
});
Person = persist.define("Person", {
"name": persist.String
}).hasMany(Phone);
### Model.hasOne(AssociatedModel, [options]): Model
Adds a has one relationship to a model. This will automatically add a property to the associated model which links to this model. It will also define a property on instances of this model to get the releated objects - see Associated Object Properties
Arguments
Returns
The model class object suitable for chaining.
Example
Phone = persist.define("Phone", {
"number": persist.String
}).hasMany(Person);
Person = persist.define("Person", {
"name": persist.String
});
### Model.using(connection): query
Gets a query object bound to a connection object.
Arguments
Returns
Example
Person.using(connection).first(...);
### Model.save(connection, callback)
Saves the model object to the database
Arguments
Example
person1.save(connection, function() {
// person1 saved
});
### modelInstance.update(connection, params, callback)
Updates the model object to the database
Arguments
Example
person1.update(connection, { name: 'Tom' }, function() {
// person1 saved
});
### Model.update(connection, id, params, callback)
Updates the model object specified with id to the database. This will only update the values specified and will not retreive the item from the database first.
Arguments
Example
Person.update(connection, 5, { name: 'Tom' }, function() {
// person with id = 5 updated with name 'Tom'.
});
// or chaining
connection.chain([
Person.update(5, { name: 'Tom' })
], function(err, results) {
// person with id = 5 updated with name 'Tom'.
});
### Model.delete(connection, callback)
Deletes the model object from the database
Arguments
Example
person1.delete(connection, function() {
// person1 deleted
});
### Model.getById(connection, id, callback)
Gets an object from the database by id.
Arguments
Example
Person.getById(connection, 1, function(err, person) {
// person is the person with id equal to 1. Or null if not found
});
### Model.onSave(obj, connection, callback)
If preset this function will be called when an update or save occures. You would typically create this method in your model file.
Arguments
Example
Person.onSave = function(obj, connection, callback) {
obj.lastUpdated = new Date();
callback();
};
### Model.onLoad(obj)
If preset this function will be called after an object is loaded from the database. You would typically create this method in your model file.
Arguments
Example
Person.onLoad = function(obj) {
obj.fullName = obj.firstName + ' ' + obj.lastName;
};
### Associated Object Properties
If you have setup an associated property using hasMany instances of your model will have an additional property which allows you to get the associated data. This property returns a Query object which you can further chain to limit the results.
Example
Phone = persist.define("Phone", {
"number": persist.String
});
Person = persist.define("Person", {
"name": persist.String
}).hasMany(Phone);
Person.using(connection).first(function(err, person) {
person.phones.orderBy('number').all(function(err, phones) {
// all the phones of the first person
});
});
## Query
### query.all([connection], callback)
Gets all items from a query as a single array of items. The array returned will have additional methods see here for documentation.
Arguments
Example
Person.all(connection, function(err, people) {
// all the people
});
### query.each([connection], callback, doneCallback)
Gets items from a query calling the callback for each item returned.
Arguments
Example
Person.each(connection, function(err, person) {
// a person
}, function() {
// all done
});
### query.first([connection], callback)
Gets the first item from a query.
Arguments
Example
Person.first(connection, function(err, person) {
// gets the first person
});
### query.last([connection], callback)
Gets the last item from a query.
Arguments
Example
Person.last(connection, function(err, person) {
// gets the last person
});
### query.orderBy(propertyName, direction): query
Orders the results of a query.
Arguments
Returns
The query object suitable for chaining.
Example
Person.orderBy('name').all(connection, function(err, people) {
// all the people ordered by name
});
### query.limit(count, [offset]): query
Limits the number of results of a query.
Arguments
Returns
The query object suitable for chaining.
Example
Person.orderBy('name').limit(5, 5).all(connection, function(err, people) {
// The 5-10 people ordered by name
});
### query.where(clause, [values...]): query
### query.where(hash): query
Filters the results by a where clause.
Arguments
Returns
The query object suitable for chaining.
Example
Person.where('name = ?', 'bob').all(connection, function(err, people) {
// All the people named 'bob'
});
Person.where('name = ? or age = ?', ['bob', 23]).all(connection, function(err, people) {
// All the people named 'bob' or people with age 23
});
Person.where({'name': 'bob', 'age': 23}).all(connection, function(err, people) {
// All the people named 'bob' with the age of 23
});
### query.whereIn(property, [values...]): query
Filters the results by a where clause using an IN clause.
Arguments
Returns
The query object suitable for chaining.
Example
Person.whereIn('name', ['bob', 'alice', 'cindy']).all(connection, function(err,people) {
// All the people named 'bob', 'alice', or 'cindy'
});
Person.include("phones").whereIn('phones.number', ['111-2222','333-4444']).all(connection, function(err,people){
// All the people whose phone numbers are '111-2222' or '333-4444'
});
### query.count([connection], callback)
Counts the number of items that would be returned by the query.
Arguments
Example
Person.where('name = ?', 'bob').count(connection, function(err, count) {
// count = the number of people with the name bob
});
### query.min([connection], fieldName, callback)
Gets the minimum value in the query of the given field.
Arguments
Example
Person.where('name = ?', 'bob').min(connection, 'age', function(err, min) {
// the minimum age of all bobs
});
### query.max([connection], fieldName, callback)
Gets the maximum value in the query of the given field.
Arguments
Example
Person.where('name = ?', 'bob').max(connection, 'age', function(err, min) {
// the maximum age of all bobs
});
### query.sum([connection], fieldName, callback)
Gets the sum of all values in the query of the given field.
Arguments
Example
Person.where('name = ?', 'bob').sum(connection, 'age', function(err, sum) {
// the sum of all ages whos name is bob
});
### query.deleteAll([connection], callback)
Deletes all the items specified by the query.
Arguments
Example
Person.where('name = ?', 'bob').deleteAll(connection, function(err) {
// all people name 'bob' have been deleted.
});
### query.updateAll([connection], data, callback)
Updates all the items specified by the query.
Arguments
Example
Person.where('name = ?', 'bob').updateAll(connection, { age: 25 }, function(err) {
// all people name 'bob' have their age set to 25.
});
### query.include(propertyName): query
Includes the associated data linked by (hasMany or hasMany(through)) the propertyName when retrieving data from the database. This will replace obj.propertyName with an array of results as opposed to the default before which is a query.
Internally this will do a join to the associated table in the case of a one to many. And will do a join to the associated through table and the associated table in the case of a many to many.
Arguments
Example
Person.include("phones").where('name = ?', 'bob').all(connection, function(err, people) {
// all people named 'bob' and all their phone numbers
// so you can do... people[0].phones[0].number
// as opposed to... people[0].phones.all(function(err, phones) {});
});
## Transaction
### tx.commit(callback)
Commits a transaction.
Arguments
Example
connection.tx(function(err, tx) {
person1.save(connection, function(err) {
tx.commit(function(err) {
// person1 saved and committed to database
});
});
});
### tx.rollback(callback)
Rollsback a transaction.
Arguments
Example
connection.tx(function(err, tx) {
person1.save(connection, function(err) {
tx.rollback(function(err) {
// person1 not saved. Transaction rolledback.
});
});
});
## Result Set
### rs.getById(id)
Gets an item from the result set by id.
Arguments
Example
Person.all(connection, function(err, people) {
var person2 = people.getById(2);
});
## Connection Pooling
### Using
Persist uses generic-pool to manage the connection pool. If you specify "pooling" in your configuration you must specify a pool name. See generic-pool for other options. To cleanly shutdown the connection pool you must also call persist.shutdown.
Example database.json to enable pooling:
{
"default": "dev",
"dev": {
"driver": "sqlite3",
"filename": ":memory:",
"pooling": {
"name": "myDatabasePool"
}
}
}
FAQs
Node.js ORM framework supporting various relational databases
We found that persist demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
A critical vm2 sandbox escape can allow untrusted JavaScript to break isolation and execute commands on the host Node.js process.

Research
Five malicious NuGet packages impersonate Chinese .NET libraries to deploy a stealer targeting browser credentials, crypto wallets, SSH keys, and local files.

Security News
pnpm 11 turns on a 1-day Minimum Release Age and blocks exotic subdeps by default, adding safeguards against fast-moving supply chain attacks.