Magic Models
A simple, free software magical node.js ORM.
For the moment, it only works with MariaDB.
Installation
npm install --python=python2
Usage
Connection
var db = host: '127.0.0.1' user: 'root' password: 'toor' db: 'foo';db;
Once you are done, you can simply quit magic-models with the following:
db; // note that if you don't do it, the program may not exit
Executing raw queries
You can make raw queries easily, with the following:
db;
Defining Models
db
Note that the name of the model is singular and the ORM will look for a table with the plural name.
To avoid this behaviour, you can specify a custom table name with the third argument of db.define
:
db;
It is also possible to specify the models directory with the following:
db
A list of directories is also possible:
db
In both of this two cases, you need to define your models in this way:
module { db;}
You can define multiple times the same model, it will be updated :
db;db;
You can avoid this behaviour by giving the erase
option to the third argument of db.define
:
db;
The models you define are in db.models
Default values
There is several ways to set default values:
default: "foo" // default value will be "foo" at the creationdefault: "foo" "bar" // default value will be "foo" at the creation and "bar" at the updatedefault: created: "foo" // default value will be "foo" at the creation and "bar" at the update modified: "bar" // you can specify only one of this two if you wantdefault: "foo-bar" // default value will be "foo-bar" at the creation and at the updatedefaultCreated: "foo" // default value will be "foo" at the creationdefaultModified: "bar" // default value will be "bar" at the updatedefaultBoth: "foo-bar" // default value will be "foo-bar" at the creation and at the update
By default, the orm will look for a createdAt
and a modifiedAt
field.
If they don't exist, the .create()
and the .update()
methods will not work.
You can change the fields looking for or avoid this behaviour with the third argument of db.define
:
db;
Models validation rules
There is several ways to define validations rules:
// type 1: custom error message with builtin rulevalidate: is: val: regExp msg: customMessage // type 2: default error message with builtin rulevalidate: is: regExp// type 3: default error message with custom rulevalidate: { ; // the validation fail if you call cb with false // never call the callback more than once, or there will be an undefined behaviour }// type 4: custom error message with several builtin rulesvalidate: custom: is: regExp not: regExp msg: customMessage // type 5: custom error message with one or several custom rulesvalidate: custom: { ; } { ; } msg: customMessage
Note that you can mix types 4 and 5 validations rules.
For the moments, the following rules are builtin:
is: /^[a-z]*$/i // also accepts a stringnot: /^[0-9]*$/ // also accepts a stringisIn: "foo" "bar"notIn: "toto" "titi"isUnique: truelen: 4 32minLen: 4maxLen: 32between: 5 10min: 5max: 10isAfter: "1474-11-13" // also accepts a date objectisBefore: "1605-11-05" // also accepts a date objectisBetween: 1474 10 13 1605 10 5) // also accepts stringsisUrl: "https://npmjs.org"isIP: "127.0.0.1" // matchs IPv4 and IPv6isIPv4: "127.0.0.1"isIPv6: "2001:db8:0:85a3::ac1f:8001"
In your custom validations rules, args will be this object:
data: data // an object containing all the values setted model: model // the model checkField: name: 'login' // the name of the field you have to check val: 'admin' // the value of the field you have to check rule: name: 'custom' // the name of the rule val: Function // the value of the rule; for a custom rule, it is the validation function msg: message // the message that will be send if validation rule fail
Models methods
Once you have defined your model, the following methods will be available:
Note that all of this methods are calling the db.query method. So, the callbacks of this methods are given to the db.query method and the arguments you will receive are the same.
db;dbmodelsUserall fields: 'login' 'password' where: id: 'gt': 5 order: id: 'DESC' group: 'login' // you can also give an array if you want to group several fields limit: 20 offset: 10 // it will work only if a limit is defined too count: true // will only return the number of rows { // getting all the rows matching, with only the fields you specified // if you no specify fields, you will get all of the fields defined in the model // note that the order, group, limit, offset and count clauses only work for the method .find, .count and .all};dbmodelsUser;dbmodelsUser;dbmodelsUser;dbmodelsUser;dbmodelsUser;dbmodelsUser
If you give the callback as the first argument of this functions, it will works well, and the object usually used as first argument will be {}
.
Where
You can combine a lot of options in the where clause:
where: id: 5 // WHERE `id` = "5" id: 1 5 // WHERE `id` IN("1", "5") id: bewteen: 1 5 // WHERE `id` BETWEEN "1" AND "5" gt: 5 // WHERE `id` > "5" gte: 5 // WHERE `id` >= "5" lt: 5 // WHERE `id` < "5" lte: 5 // WHERE `id` <= "5" ne: 5 // WHERE `id` != "5" eq: 5 // WHERE `id` = "5" not: 5 // WHERE `id` NOT "5" login: like: "%admin%" // WHERE `login` LIKE "%admin%" match: /[a-z]*/i // WHERE `login` REGEXP "[a-z]*" or: // WHERE ((`id` = "5") OR (`login` = "admin")) id: 5 login: "admin"
You can combine all of this, including AND and OR, priorities will be respected.
where: or: type: 'dog' color: 'white' size: 'large' type: 'cat' or: size: 'small' color: 'black'
It'll generate the following request:
WHERE ((`type` = "dog" AND `color` = "white" AND `size` = "large") OR (`type` = "cat" AND ((`size` = "small") OR (`color` = "black"))))'
Hooks
You can add functions that will be called before and after each method.
The following hooks are supported :
;;;;;;;;;;;;
Order of operations
Create
// beforeValidatevalidate// afterValidate// beforeCreate// beforeSavecreate// afterSave// afterCreate
Update
// beforeValidatevalidate// afterValidate// beforeUpdate// beforeSaveupdate// afterSave// afterUpdate
Delete
// beforeDeletedelete// afterDelete
Find
// beforeFindfind// afterFind
Declaring hooks
Hooks have to be declared in the third parameter of db.define
.
db;
Note that if you don't call the callback, it will results to an undefined behaviour.
In the case of an update, the param datas
will only contain the new values, not the where informations.
Contributing
If you think a feature is missing, you can open an issue, or try to make it and then do a pull request.
If you find a bug, open an issue too. You can also fix it and do a pull request.
If you think this doc is incomplete, you can improve it the same way.
Author
Emeraude