Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
simple-sql-model
Advanced tools
A simple model wrapper around the
sql
library with helpful query functions.
This provides a bunch of convenience methods to create simple DB models quickly in a Rails-style query layout.
sql
module; you should check the source in model.js
and the tests in model.test.js
to see what's going on. I swear, it's really simple.async
/await
, Class
so use Node 7.8+ or above or transpile using Babel or similar.sql
module supportsModel.create
, Model.update
, Model.destroy
)Model.findOne
, Model.findMany
)Model.count
)model.update
, model.destroy
)Model.beforeCreate
, Model.afterCreate
, Model.beforeUpdate
, Model.afterUpdate
, Model.beforeDestroy
, Model.afterDestroy
)or
/and
style queriesuppercase
, lowercase
, etc)updatedAt
and createdAt
# npm
npm i -S simple-sql-model
# or yarn
yarn add simple-sql-model
const Connect = require('pg-promise')()
const Model = require('simple-sql-model')
// Connect to a Postgres DB. The connection can
// be to any SQL compatible DB that the `sql`
// module supports. The returned connection
// object must provide a Promise returning `query`
// method to be compatible.
const connection = Connect({
database: 'my-db',
user: 'myuser',
})
class Account extends Model {}
Account.configure({
connection,
table: 'accounts',
columns: [ 'id' ],
})
class User extends Model {
//---------------------------------------
// Instance methods
//---------------------------------------
toString() {
return this.name
}
//---------------------------------------
// Class methods
//---------------------------------------
static myCustomClassMethod() {
// do some magic here...
}
// before/after hooks:
static beforeCreate(fields) {}
static afterCreate(model, fields) {}
static beforeUpdate(model, fields) {}
static afterUpdate(model, fields) {}
static beforeDestroy(model) {}
static afterDestroy() {}
}
// Setup the database connection for the model.
User.configure({
// The DB connection to use. Must provide a Promise
// returning `query` function to be compatible.
connection,
table: 'users',
// Define columns in the table
columns: [
'id',
'accountId', // foreign key
'name',
'isAdmin', // gets snake-cased to `is_admin`
],
// Define any foreign key references. We auto-expand
// these refernces into their respective model
// instances.
references: {
account: { // expands associated model into `model.account`
model: Account,
key: 'accountId',
},
},
})
//-------------------------------------------------------
// Create rows
//-------------------------------------------------------
// Save row directly.
const user = await User.create({ name: 'John' })
// Initialize model instance and then save it to the DB.
const user2 = new User({ name: 'Bill' })
await user2.save()
//-------------------------------------------------------
// Update rows
//-------------------------------------------------------
await User.update(user.id, { name: 'Johnny' })
user.name = 'Johnny'
await user.save()
// or:
await user.save({ name: 'Johnny' })
//-------------------------------------------------------
// Find rows
//-------------------------------------------------------
await User.findOne(user.id)
// Returns first match from query
await User.findOne({
where: { name: { equals: 'John' } },
})
// Returns all users
await User.findMany()
// Returns array of the first 5 matches ordered by first name
await User.findMany({
where: { name: { equals: 'John' } },
order: { name: 'asc' },
limit: 5,
})
//-------------------------------------------------------
// References
//-------------------------------------------------------
const account = await Account.create()
const user = await User.create({
accountId: account.id,
name: 'Joe Blow',
})
user.account // same as `account` model instances
//-------------------------------------------------------
// Count number of rows
//-------------------------------------------------------
await User.count()
await User.count({
// includes j in name (case-insensitive)
where: { name: { ilike: '%j%' } },
})
//-------------------------------------------------------
// Delete rows
//-------------------------------------------------------
await user.destroy()
await User.destroy(user.id)
await User.destroy({ where: { name: { equals: 'John' } } })
// Destroys everything so we want to make sure you
// want this to happen!
await User.destroyAll({ yesImReallySure: true })
//-------------------------------------------------------
// Other helpful methods
//-------------------------------------------------------
User.toString() //=> 'User'
String(User) //=> 'User'
User.tableName // => 'users'
User.columns // => [ 'id', 'name', 'isAdmin' ]
A lot of the built in class methods allow you to pass in an ID or a query object to find matching rows.
The ID can be a Number
or a String
(eg 1
or '1'
).
The query object looks like this:
{
where: {
name: { equals: 'John' },
},
order: {
name: 'desc',
},
limit: 5,
}
Checkout this page on the available where
options. Also check out the test in this project for more examples.
Model.configure({ connection, columns, references, table })
This must be called to connect your model to a SQL database.
undefined
connection
- A connection to a SQL database that provides a Promise aware .query()
method. This query
method is what simple-sql-model
will pass SQL strings to. It expects the results to be return directly (eg a Object
representing a row or an Array
representing a set of rows).columns
- An Array
of table column name String
s that map to your schema. They can be in snake_case or camelCase as we always convert to snake_case when converting queries to SQL.references
(optional) - An object representing a mapping between a foreign key and it's model. By creating references, we will automatically expand any associated models.table
- The name of the table in your database to connect to (eg 'users'
or 'products'
).Model.create(fields)
Creates a new row in the DB with the given fields and returns a new model instance.
Model
instance.fields
- The fields to create the new model from. Must match the schema.Model.beforeCreate(fields)
If defined in child class, gets called before a Model
is created.
Model.create()
fields
- The fields passed to Model.create()
Model.afterCreate(model, fields)
If defined in child class, gets called after a Model
is created.
Model.create()
model
- The Model
instance of the created row.fields
- The fields passed to Model.create()
Model.findOne(idOrQuery)
Finds one (or no) rows based on the given ID or query.
Model
instance of the matched row or null
.idOrQuery
- An ID (Number
or String
) or query object to find the row in the table.Model.findMany(query)
Finds one or more rows based on the given ID or query.
Array
of Model
instances of the matched row or an empty array ([]
).idOrQuery
- An ID (Number
or String
) or query object to find the row in the table.Model.update(idOrQuery, changes)
Updates a row in the table with given changes based on an ID or query.
Model
instance.idOrQuery
- An ID (Number
or String
) or query object to find the row in the table.changes
- An Object
of the changes to the row. This can be one, some or all of the columns in the given table to change (eg partial or full updates are possible).Model.beforeUpdate(model, fields)
If defined in child class, gets called before a Model
is updated.
Model
instance before modification and the fields that were passed to Model.update()
model
- The Model
instance before updating.fields
- The fields passed to Model.update()
Model.afterUpdate(model, fields)
If defined in child class, gets called after a Model
is updated.
Model.update()
model
- The Model
instance of the updated row.fields
- The fields passed to Model.update()
Model.destroy(idOrQuery)
Deletes a row from the table based on an ID or query.
undefined
idOrQuery
- An ID (Number
or String
) or query object to find the row to delete in the table.Model.beforeDestroy(model)
If defined in child class, gets called before a Model
is destroyed.
Model
instance before destroyingmodel
- The Model
instance of the updated row.Model.afterDestroy()
If defined in child class, gets called after a Model
is destroyed.
undefined
Model.count([query])
Count up the number of matching records in the table. If an optional query is passed in, count the number of rows that match the query.
Number
) of matching rows or 0
.query
(optional) - The query to use to limited the returned rows. If no query provided, it returns total amount of rows for this table.Model.className
String
Model.connection
Model.tableName
Model.columns
Array
of column names.model.save(fields)
Create or update the given model instance. If the model is persisted to the DB, we update it, otherwise we create a new row.
fields
(optional) - An Object
of fields to update.model.destroy()
Model.destroy()
but no ID is required.# Setup the right node version using nvm
nvm install
nvm use
# Install deps
npm install
# Create a Postgres database named "simple-sql-model-test"
# Setup database table
# Update the DB username if necessary by passing DB_USERNAME=yourname
./setup.sh
npm test # or npm run watch-test
Please see the prettier.opts
file for prettier confiuration. You should run npm run format
when making changes. We have a pre-commit hook setup to do this for you before you commit in case you forget 👍 (coming soon...)
model.save()
which will allow for direct updating without setting properties first.npm run format
as well as a pre-commit hookreferences
to Model.configure
which will automatically expand any associated models automatically.async
/await
model.update()
in favor of a better model.save
that creates or updates depending on if the instance is persisted in the DB.model.className
getter to return constructor class name.Model.beforeCreate
, Model.afterCreate
, Model.beforeUpdate
, Model.afterUpdate
, Model.beforeDestroy
, and Model.afterDestroy
.Model.schema
to Model.columns
.model.save()
method to create a row from an unsaved model instance.model.update()
and model.destroy()
instance methodsasync
/await
supportInitial release. Implement create
, update
, destroy
, findOne
, findMany
, and count
.
Licensed under an MIT license by Dana Woodman.
Pull requests welcome!
FAQs
Simple model wrapper around a `sql` table.
The npm package simple-sql-model receives a total of 18 weekly downloads. As such, simple-sql-model popularity was classified as not popular.
We found that simple-sql-model 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
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.