From 93dd0eb28705babd12e647daef5305f310f43602 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Tue, 23 Jul 2013 15:19:35 -0700 Subject: [PATCH] Update docs for loopback-data --- docs/connector.md | 135 +++++++++++++++++++++++++++++++++++++++++- docs/data-source.md | 61 +++++++++---------- docs/hooks.md | 9 +-- docs/index.txt | 6 -- docs/loopback-data.md | 2 +- docs/model.md | 13 ++-- docs/validations.md | 20 ++++++- media/mysql.ico | Bin 894 -> 0 bytes media/sqlite.png | Bin 4258 -> 0 bytes 9 files changed, 194 insertions(+), 52 deletions(-) delete mode 100644 docs/index.txt delete mode 100644 media/mysql.ico delete mode 100644 media/sqlite.png diff --git a/docs/connector.md b/docs/connector.md index f1d51e07..b83387d0 100644 --- a/docs/connector.md +++ b/docs/connector.md @@ -1,5 +1,134 @@ -# loopback-connector +# loopback-data-connector + +Loopback connectors provide access to backend systems including databases, REST APIs +and other services. Connectors are not used directly by application code. We create +a DataSource to interact with the connector. + +For example, + + var DataSource = require('loopback-data').DataSource; + var oracleConnector = require('loopback-connector-oracle'); + + var ds = new DataSource(oracleConnector, { + host : '166.78.158.45', + database : 'XE', + username : 'strongloop', + password : 'str0ng100pjs', + debug : true + }); + +The connector argument passed the DataSource constructor can be one of the following: + +* The connector module from `require(connectorName)` +* The full name of the connector module, such as 'loopback-connector-oracle' +* The short name of the connector module, such as 'oracle', which will be converted to 'loopback-connector-' +* A local module under ./connectors/ folder + +## Generic connector implmentations + +A connector module can implement the following methods to interact with the datasource. + + exports.initialize = function (dataSource, postInit) { + + var settings = dataSource.settings || {}; // The settings is passed in from the dataSource + + var connector = new MyConnector(settings); // Construct the connector instance + dataSource.connector = connector; // Attach connector to dataSource + connector.dataSource = dataSource; // Hold a reference to dataSource + + /** + * Connector instance can have an optional property named as DataAccessObject that provides + * static and prototype methods to be mixed into the model constructor. The property can be defined + * on the prototype. + */ + connector.DataAccessObject = function {}; + + /** + * Connector instance can have an optional function to be called to handle data model definitions. + * The function can be defined on the prototype too. + * @param model The name of the model + * @param properties An object for property definitions keyed by propery names + * @param settings An object for the model settings + */ + connector.define = function(model, properties, settings) { + ... + }; + + connector.connect(..., postInit); // Run some async code for initialization + // process.nextTick(postInit); + } + +Another way is to directly export the connection function which takes a settings object. + + module.exports = function(settings) { + ... + } + +## CRUD connector implmentations + +To support CRUD operations for a model class that is attached to the dataSource/connector, the connector needs to provide +the following functions: + + /** + * Create a new model instance + */ + CRUDConnector.prototype.create = function (model, data, callback) { + }; + + /** + * Save a model instance + */ + CRUDConnector.prototype.save = function (model, data, callback) { + }; + + /** + * Check if a model instance exists by id + */ + CRUDConnector.prototype.exists = function (model, id, callback) { + }; + + /** + * Find a model instance by id + */ + CRUDConnector.prototype.find = function find(model, id, callback) { + }; + + /** + * Update a model instance or create a new model instance if it doesn't exist + */ + CRUDConnector.prototype.updateOrCreate = function updateOrCreate(model, data, callback) { + }; + + /** + * Delete a model instance by id + */ + CRUDConnector.prototype.destroy = function destroy(model, id, callback) { + }; + + /** + * Query model instances by the filter + */ + CRUDConnector.prototype.all = function all(model, filter, callback) { + }; + + /** + * Delete all model instances + */ + CRUDConnector.prototype.destroyAll = function destroyAll(model, callback) { + }; + + /** + * Count the model instances by the where criteria + */ + CRUDConnector.prototype.count = function count(model, callback, where) { + }; + + /** + * Update the attributes for a model instance by id + */ + CRUDConnector.prototype.updateAttributes = function updateAttrs(model, id, data, callback) { + }; + + -Loopback data sources are backed by connectors that communicates with backend systems including databases, REST APIs -and other services. diff --git a/docs/data-source.md b/docs/data-source.md index 9400c478..aceb6773 100644 --- a/docs/data-source.md +++ b/docs/data-source.md @@ -1,42 +1,43 @@ -loopback-connector-schema(3) - Everything about schema, data types and model definition. -==================== +# loopback-data-datasource + +Everything about datasource, data types and model definition. ## DESCRIPTION -Schema is a factory for classes. Schema connected with specific database using -adapter. +DataSource is a factory for model classes. DataSource connected with specific database or other +backend system using connector. -All classes within single schema shares same adapter type and one database -connection. But it's possible to use more than one schema to connect with +All model classes within single datasource shares same connector type and one database +connection. But it's possible to use more than one datasource to connect with different databases. ## EVENTS -Instances of Schema are event emitters, events supported by default: +Instances of DataSource are event emitters, events supported by default: * `.on('connected', function() {})`: Fired when db connection established. Params: none. * `.on('log', function(msg, duration) {})`: - Fired when adapter logged line. Params: String message, Number duration + Fired when connector logged line. Params: String message, Number duration ## USAGE -### Creating schema +### Creating dataSource -`Schema` constructor available on `loopback-data` module: +`DataSource` constructor available on `loopback-data` module: - var Schema = require('loopback-data').Schema; + var DataSource = require('loopback-data').DataSource; -Schema constructor accepts two arguments. First argument is adapter. It could be -adapter name or adapter package: +DataSource constructor accepts two arguments. First argument is connector. It could be +connector name or connector package: - var schemaByAdapterName = new Schema('memory'); - var schemaByAdapterPackage = new Schema(require('redis')); + var dataSourceByConnectorName = new DataSource('memory'); + var dataSourceByConnectorModule = new DataSource(require('redis')); ### Settings Second argument is optional settings. Settings object format and defaults -depends on specific adapter, but common fields are: +depends on specific connector, but common fields are: * `host`: Database host @@ -51,21 +52,21 @@ Database name * `debug`: Turn on verbose mode to debug db queries and lifecycle -For adapter-specific settings refer to adapter's readme file. +For connector-specific settings refer to connector's readme file. ### Connecting to database -Schema connecting to database automatically. Once connection established schema +DataSource connecting to database automatically. Once connection established dataSource object emit 'connected' event, and set `connected` flag to true, but it is not necessary to wait for 'connected' event because all queries cached and executed -when schema emit 'connected' event. +when dataSource emit 'connected' event. -To disconnect from database server call `schema.disconnect` method. This call -forwarded to adapter if adapter have ability to connect/disconnect. +To disconnect from database server call `dataSource.disconnect` method. This call +forwarded to connector if connector have ability to connect/disconnect. ### Model definition -To define model schema have single method `schema.define`. It accepts three +To define model dataSource have single method `dataSource.define`. It accepts three argumets: * **model name**: @@ -81,14 +82,14 @@ argumets: Examples of model definition: - var User = schema.define('User', { + var User = dataSource.define('User', { email: String, password: String, birthDate: Date, activated: Boolean }); - var User = schema.define('User', { + var User = dataSource.define('User', { email: { type: String, limit: 150, index: true }, password: { type: String, limit: 50 }, birthDate: Date, @@ -103,7 +104,7 @@ Examples of model definition: ### DB structure syncronization -Schema instance have two methods for updating db structure: automigrate and +DataSource instance have two methods for updating db structure: automigrate and autoupdate. The `automigrate` method drop table (if exists) and create it again, @@ -112,15 +113,15 @@ called when migration/update done. To check if any db changes required use `isActual` method. It accepts single `callback` argument, which receive boolean value depending on db state: false if -db structure outdated, true when schema and db is in sync: +db structure outdated, true when dataSource and db is in sync: - schema.isActual(function(err, actual) { + dataSource.isActual(function(err, actual) { if (!actual) { - schema.autoupdate(); + dataSource.autoupdate(); } }); ## SEE ALSO -loopback-connector-model(3) -loopback-connector-adapter(3) +loopback-data-model +loopback-data-connector diff --git a/docs/hooks.md b/docs/hooks.md index 5c39b9df..f072329a 100644 --- a/docs/hooks.md +++ b/docs/hooks.md @@ -1,5 +1,6 @@ -loopback-connector-hooks(3) - Hooks and object lifecycle. -=================== +# loopback-data-hooks + +Hooks and object lifecycle. ## DESCRIPTION @@ -130,5 +131,5 @@ loopback-connector-validations(3) man section. ## SEE ALSO -loopback-connector-model(3) -loopback-connector-validations(3) +loopback-data-model +loopback-data-validations diff --git a/docs/index.txt b/docs/index.txt deleted file mode 100644 index d3cf385a..00000000 --- a/docs/index.txt +++ /dev/null @@ -1,6 +0,0 @@ -# adapters github -loopback-connector-mongodb https://github.com/strongloop/loopback-connector-mongodb -loopback-connector-oracle https://github.com/strongloop/loopback-connector-oracle -loopback-connector-mysql https://github.com/strongloop/loopback-connector-mysql - -# external resources diff --git a/docs/loopback-data.md b/docs/loopback-data.md index 82e8a0bf..a6e6f644 100644 --- a/docs/loopback-data.md +++ b/docs/loopback-data.md @@ -4,4 +4,4 @@ Loopback-data provides ORM and data connectivity for Node.js. It was initially f ## SEE ALSO -loopback-connector +loopback-data-connector diff --git a/docs/model.md b/docs/model.md index bbaa4bc7..c59b8964 100644 --- a/docs/model.md +++ b/docs/model.md @@ -1,5 +1,6 @@ -loopback-connector-model(3) - Model methods, features and internals -=================== +# loopback-data-model + +Model methods, features and internals ## DESCRIPTION @@ -185,7 +186,7 @@ TODO: document ## SEE ALSO -loopback-connector-schema(3) -loopback-connector-validations(3) -loopback-connector-hooks(3) -loopback-connector-adapter(3) +loopback-data-datasource +loopback-data-validations +loopback-data-hooks +loopback-data-connector diff --git a/docs/validations.md b/docs/validations.md index 53dd4bc1..3621036f 100644 --- a/docs/validations.md +++ b/docs/validations.md @@ -1,2 +1,18 @@ -loopback-connector-validations(3) - Built-in validators, creating custom validations, syncronous and asyncronous object validation. -======================== +# loopback-data-validations + +Built-in validators, creating custom validations, syncronous and asyncronous object validation. + + // Setup validations + User.validatesPresenceOf('name', 'email') + User.validatesLengthOf('password', {min: 5, message: {min: 'Password is too short'}}); + User.validatesInclusionOf('gender', {in: ['male', 'female']}); + User.validatesExclusionOf('domain', {in: ['www', 'billing', 'admin']}); + User.validatesNumericalityOf('age', {int: true}); + User.validatesUniquenessOf('email', {message: 'email is not unique'}); + + user.isValid(function (valid) { + if (!valid) { + user.errors // hash of errors {attr: [errmessage, errmessage, ...], attr: ...} + } + }) + diff --git a/media/mysql.ico b/media/mysql.ico deleted file mode 100644 index 918e89d32d8ae3b4993f95e5b3a180e0c216651f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 894 zcmZQzU<5(|0RaXO$Y5q*5ChU0KnxO50AfZ42_OjsKsh092!;qSF#M+txO!;Ly;Ez5 zG<(b3sCU=);#B z4~wYL+ne{D`TqXq&N;uCGjsmCb7yX{v7r_f#S;nu06?Xq4Ke*o(0@gC@2^`DUcC8> zd(L`V5WwAkr?k5&=WjwDp#2>Bm)if6=CHT&f5VpnY94?2zdm4mFVzwNcrdC1Q8V*g z?#~N@+i4UHs+foDEVrNZR7`QR(5aIpbCSn#6DP8$C2~2gZ><7j10g2dDC&{CtiV6O zceFr{f45T8SF1zWi3ItFp3rcsGc*VD6=hZ`;JLfccA|D7&z5U1)=#o|S#$>7whO^0 zv$gx1mc5rVjoTEr`Wv-k|GYMl82?9Hs|fF9k`++NJoRJ1&STzs$~z$vRk2~&^YW|K z8;>82$5k{}vS-WaYTk`os6oj3o8pD#B3;~ptS+w7Dwc*pfS8b9_7g*OTbA7})0HKr zFfWzo4%uhJ7G)K=TCj2%HWmT~ilC}yf9G$&bxAAe^(p}ZSjZ#w(h6?=1bB+tcwlR; zu1xg#?Ul=&m}CInve)|2p7JE^+fm*LbEok6JIGd2cLO~+ha(ChVnnY=AJ6{5zxts% z()GI-9faWrp3(TaWgL?-b2iY8!Bw{T9JR*RVZC=0j#tc0Ez;0>xFbhY(ogO5#9F~A ziGA*>txdBsD**fEo732tx+zJfs|-RKqXge{x-@I@Rysx(2l|v9UJKkXvH=TJ-8I9`C`1o>aD%XAZsrEhalmb-mX@T8G1d zqY5s*;z{Eosr+d^4%Kz2x7Kiq50%$D@18PybNCZ|rox zbVP9wXXOT;Z0g95^BG~0l7v=)XLF)c>7gZc!^Eg_S|dH_J>>?j@99_=Enb%Tqo;jN z=dW7xpjVs9_ueF$=pycV)qsWNR+8I%J9y<=!7vKQR(pr?=B(WlKQ zEz@G;n2eSpU#BzPf?b91DOWTCs*h3Omluy8E(1LHc$Av;?dn&4T z7#h?BsQASoy`!sH;1<~uu+j!~Z!Pjx`mRqe zDb1y4+&A1dN8^Vk4R=$j)%}@Gd_c~wzWq>>5NjEKo zr)>RmPT3VqY8m!4$_4K0*IhR&XH7YH401|x;D;<62Sv%`h%!)IrTItUnOHk62*RUF zln<|ZY{Ms%{Bn{vv&9E>IxuffB}uz zPW(Hs(?z7+KB%rT3o_E5)`=AqtoF)JJIa=`2Ufa}2{7#{Yp-q&Q&$P3y5ghCbJo5p z-Qd1t-PMd9Brwk!=YPLHO*%Z|r!TjMT=e8Q2$r8!xj6S0cIX@{Z1(I~nqH1|5Tu1Z za+LSl(m>p647facrrp1D;LIRf7U--~7)rs1=p##pQ^4P5iK>&;=DX7}K+UGPlT+l~ z+s(2K#5{*mA+J7lUoQ;y9=GEsqIa*ZcLEy;CN}nMrHgsBof|m+eNlXIqA6Hcw~H24 z{=1g#C2QZmH%}}k@hCkA(wXwJuy2ilZ>!fS{xBh{QROdPqNt(O(;|Lc3P`~$yK8TGkfVo zyNh#!kM_~Jsjkpq7O-L<#MaDq0tamtj(W|K5SuRkJ*ZhXIrBv`1&O+2IoU%Jh*L~5 zCyF1FItSvW(1UA&tmaa zt>#C(&+Ynm7GH6|Ff-KYr`2+QfI^Mv^s??o&I$-w0*y=FCPZieQA~1QMwphq1s28n zkU_jGgNn$95wS>)q{BCS`|zSW-E>HW6-q@Gw{Kp#WN1`J$uew}&6^yS-)7{GJyt{% zMk1Exd){`jv6K9|rm37(b(1o4P}mnfMUx9_6>?Q!Dc-id_raGEBaW^>>=YEpQf+#M zWOcTO2#`|@6%ncw!idnG7SVk1-B<=w;87Y9qPQ_U>YW{g&hB!t?b;N)7ybtKsXj-j zv0D)=2O7f!WrC(rgJy&6mun^DG2WSL}g!jSw}2oDOwC-^8yS03eDJTyUj5r#4?o}74yID+*PRyr4hgvFyb(#(n?loX0D zmz%zNwrwt16-}EBp4iT1SqrKCJq{}~dULVLemBz&3q@C-Gy7KMQ#$IBymXe#J6x1V z^3;ATMnO)pndNV`kB3hcC$`G!={3XE!1Lk-xFH&yWK~CBGkZ)~hQNgzK;@0GXb7dn zWXCUeA1_$?pkKLM1dVqFNv0W8Xg#GCmcK8s7HYlb)xXeYV->Lw!L=SJE!Xu9SxnD1 zMOQBz_^P>%UuA5F`9W48l(*)6ZiTx8*(}G9Po>o70@H>EDByr9eQbbj7vz!lgTZ>$ zPIK;U1eX~FbLx+kLznP{67DhTbe6c??*KiU{lJ{SqFP-!Gwh5+J!Cw@^`F}Y)=N^& z(20<_15FPPoNqeKJ~;CLXq{g$*tjr2Eo?mUGG6c}cRsr?%H`YEub}J~pV30mK519T zk8IJwqdMbp;49R%0fBT&SSAh6J5?poW3En8a*DMrZ9tZis@XPpvF? zL#MYf0De9K8{B%@<(vU zS<6uz6t5hC>`=gi8;II+bzXSygjM>oeeH~Zx8{w_etT`KYtShXJM8l7+?S-1m48Zd`4rtX75^_N35fXAmm$LoK$>o$+n9rNf%vYDw0C zH-kD-GDlb=Ha-e1+Ee!9bl${@+XZ(h$@F!Z=k zd-vSf$tYbB%b2ont6@h%eDJxkg-sSlO&z8izx);l3|X(9GmErP%|&!P%JE-M;s+*+}^Xr5@L>tfccpNNr2hCh4xl&g06lz_qh)NuPuQFA@rgK2l$@$56TJxjt6 z8J+k6QMLcr=Ru?CgZ}04-zo$5L&x{& z8p1PX?XRBg$WX=VOOH2%5OWj@tvArMW9Z z$4qnKcEX%-_d)!80DL!=ZwR=QRDv%|rM_$*xv@P_U#MBDtx^AV!7{z?b$OM<$g`2Q9G3YnTV>zi67i1Z zL1vP1o~C!)m_+}GJbaaCh&mWkYS_>ZOAVB zfC_O!eCEC;<699o8ha(wPyGO;0HLO)u=8^CVar$IPA6SlS@I}>0MB=+b^YOl+nrBF z5$Ls_v)(3`>Kr_?V%-s4KdXr3DBQd5bsKLDToyS_&0~kjLIjPa-C7hZ=9PE>7|g*I zeq#zQJb(JQd8{;5>&?pJ{i>MMw?OaTQp~tu$tSR!5(A~l4;?55jwcB;R!;5_4qn19 z1Ndd9dRbo4s)MAQ$@_*?rASmse)5VZ3S{~hVi@}^Wp|$nB*3Gm`8qZRn{}I-L?B7S zRmf+WO&0bthotkMb+y&bQ@f`={yX_Ga>akv>R}oCW9ZXMpA}Lo))H2LA#*fK-d0&2 zwTxhgnoeT$>G6q=)m-{)a+58;v`Z!zlw&Y(enEL;-J4STOTcHu0|QF-k7+JqZ+*hI zPx1(t+7sg}gy})&TTjJ~Z~P-l%8ErXBqkY|hwWnt0~$h=lh%@Q#;bfPxN)%(R%~BP zh*ihGNkRhx?pYpoOayeJLhe&Jn?;yZqRE96FmAJKGQd|{Ra9Y9YPoY;YFw_I)s1VY zm*7G)^NHzOjxdS}gp&*T2R6_`dv2PTuj^Mm-&TJ%Re{vFlC;_5TWN3JPw`#^!j4ow zO=Xl1uagN=-_2MW3rXGCQG~tnOiJJw^O_y=dYO#Yc*5*bv7OI2KEMRbN_7>!0-pw* z2T%*B38jo2>C+!(T{-06A}+rHc!+JjCGxFYyh(|MUSQGBd5C2flO#EZ<3L#H#0mii zCXP}NgB`fCR3vlh?yJZ1D~p?3Hn@M005v-|?(dJ!6Rcqs>=NYW6znGA`quywAaRfg zNJ>OP(hMXImXHEVN(+HNU=WD(wZ+K)6@2|&z1+k8pMup0`|aNXKu5z6(xC1b_aAv| BCvN}%