An awesome, define-once, use anywhere ORM.
Note: These docs are in the process of being written. The code examples are up to date, but not exhaustive.
To use with NPM:
npm install --save intaglio
To use with Bower
bower install --save intaglio
To get up and running quickly with Node and MySQL, here's how you would instantiate the ORM:
var Intaglio = require'intaglio';/*** Instantiate the MySQL repository that the ORM will bind to.*/var repository = mysqlhost: "localhost"user: "db_user"password: "password"database: "database_name";/*** Create an ORM to work with. This returns a promise because the ORM must wait* for the repository to become ready. The MySQL repository makes a few queries* on instantiation to get the database structure. We can't start using it until* these calls have completed.*/IntaglioORMcreaterepositorythen/*** ORM is now ready to be used. Let's grab a user with an ID of 1. This will* return a promise for us to use.*/ORMfactory'user'find1then// Do stuff with user. Would output email@example.com'email';// Update the user and save the modeluserset'email' 'firstname.lastname@example.org'savethen// Out: Updated the email to email@example.com'Updated the email to' userget'email';;;;
Currently, Intaglio ships with a MySQL and a REST respository (designed to be used with the Intaglio based REST server) to get you up and running quickly. The MySQL repository will use database introspection to define your model schema so all you need to provide are the connection details to get started using with Node. The REST repository comes with a Request based driver as well as a jQuery based one to be used on the front end.
The ORM should be pretty easy to use, but there are some things to keep in mind. We made some design decisions to make the implentation simpler and easier to maintain.
The ORM will not care what names you use on the repository side, but it will normalize them to make it easier to code around. All model names and property names will be normalized to camelCase. Model names will also be made singular. So if your repository provides a model named
user_profiles, it will be normalized to
The ORM will expect some sort of primary key to bind to. Also, while multiple column keys can be used, they are not well tested, so if you use them, let us know what issues you run into.
In the following examples, we'll use a
user model that has the following schema:
- id (Primary Key)
// Create an empty user objectvar user = ORMfactory'user'create;// Set a single value to the objectuserset'email' 'firstname.lastname@example.org';// Set multiple values to the objectusersetfirstName: "Jeffery"lastName: "Lebowski";// Save the object. This returns a promise.usersavethenconsole.info'User created with an ID of' userget'id';;// Create an object with values and save itORMfactory'user'createfirstName: "Walter"lastName: "Sobchak"email: "email@example.com"savethenconsole.info'User created with an ID of' userget'id';;
In order to make things easy to use, Intaglio relies on natural language chain style queries:
// Finds and returns the first model in the repository that has the firstName of DonnyORMfactory'user'where'firstName'isEqual'Donny'findthen// If no user was found, user will be nullif user === nullthrow 'Could not find Donny!';;// Finds and returns all models in the repository that have the firstName of DonnyORMfactory'user'where'firstName'isEqual'Donny'findAllthen// If no user was found, user will be an empty arrayif userslength === 0throw 'Could not find Donny!';console.info'Number of Donnys found:' userslength;;// Finds a user with an id of 1ORMfactory'user'find1then// Do stuff with user. Would firstname.lastname@example.org'email';;
ORMfactory'user'find1then// Do stuff with user. Would output email@example.com'email';// Update the user and save the modeluserset'email' 'firstname.lastname@example.org'savethen// Out: Updated the email to email@example.com'Updated the email to' userget'email';;;
ORMfactory'user'where'firstName'isEqual'Donny'findthen// Delete Donnydonnydeletethenconsole.info'Goodnight, sweet prince.';;;
To add methods to models or override functionality, you can extend the model. If you override a method, you can access the original method using
// Extend the user modelORMextend'user'console.infothisget'firstName' ':' said;thistrigger'spoke';console.info"I'm saved!";return this_superapplythis arguments;;
The models in the ORM have a few built in events that you can bind to:
// Load WalterORMfactory'user'where'firstName'isEqual'Walter'findthenwalteron'saved'if metachangedlength > 0console.info'Walter was updated!';;// Will log 'Walter was updated!' once the save is completewalterset'email' 'firstname.lastname@example.org'save;// To trigger an event: Will log 'Walter was updated!'waltertrigger'saved';;
// Extend the user model to add a custom functionality that triggers a custom eventORMextend'user'console.infothisget'firstName' ':' said;thistrigger'spoke' said;;var Walter Donny;// Load WalterORMfactory'user'where'firstName'isEqual'Walter'findthen// Set Walter so we can use him in other callbacksWalter = walter;// Load Donnyreturn ORMfactory'user'where'firstName'isEqual'Donny'find;then// Set Donny so we can use him in other callbacksDonny = donny;then// Setup the eventsDonnyon'spoke'Waltersay'Shut the fuck up, Donny!';;// Are those the Nazis, Walter?Donnysay'I am the walrus.';;