{
  "name": "node-mysql",
  "description": "A wrapper of node.js mysql package to make it a bit easier to use.",
  "main": "./lib/node-mysql",
  "author": {
    "name": "Chiyan Chen"
  },
  "version": "0.3.4",
  "repository": {
    "type": "git",
    "url": "https://github.com/redblaze/node-mysql.git"
  },
  "bugs": {
    "url": "https://github.com/redblaze/node-mysql/issues"
  },
  "licenses": [
    {
      "type": "MIT",
      "url": "https://github.com/redblaze/node-mysql/raw/master/LICENSE"
    }
  ],
  "jam": {
    "main": "lib/node-mysql.js",
    "include": [
      "lib/node-mysql.js",
      "README.md",
      "LICENSE"
    ]
  },
  "dependencies": {
    "better-js-class": "*",
    "cps": "*",
    "mysql": "*",
    "underscore": "*"
  },
  "readme": "# node-mysql\n\nAn enhancement to the mysql lib to make it a bit easier to use.  Based on the existing funtionalities of (npm) mysql, it also\n\n* Handles transactions.\n* Provides a simple ORM, which\n  * Detects table schema automatically.\n  * Provides handy functions for creating and updating rows.\n  * Handles optimistic lock through versioning transparently.\n  * Maintains \"date_created\" and \"last_updated\" automatically.\n  * Provides database row level lock functionality.\n\n## Install\n\n```text\nnpm install node-mysql\n```\n\n### Dependencies\n\n```json\n    \"dependencies\": {\n        \"better-js-class\": \"*\",\n        \"cps\": \"*\",\n        \"mysql\": \"*\",\n        \"underscore\": \"*\"\n    }\n```\n\n## Use\n\n```javascript\nvar db = require('node-mysql');\nvar DB = db.DB;\nvar BaseRow = db.Row;\nvar BaseTable = db.Table;\n```\n\n## APIs\n\n* DB\n  * [new DB](#new-DB)\n  * [db.connect](#db-connect)\n  * [db.transaction](#db-transaction)\n  * [db.cursor](#db-cursor)\n  * [db.end](#db-end)\n  * [db.add](#db-add)\n  * [db.get](#db-get)\n  * [DB.format](#DB-format)\n* Table\n  * [new Table](#new-Table)\n  * [table.create](#table-create)\n  * [table.clone](#table-clone)\n  * [table.find](#table-find)\n  * [table.findById](#table-findById)\n  * [table.lockById](#table-lockById)\n  * [table.findAll](#table-findAll)\n  * [table.baseQuery](#table-baseQuery)\n  * [table.linksTo](#table-linksTo)\n  * [table.linkedBy](#table-linkedBy)\n  * [table.relatesTo](#table-relatesTo)\n* Row\n  * [new Row](#new-Row)\n  * [row.update](#row-update)\n  * [row.updateWithoutOptimisticLock](#row-updateWithoutOptimisticLock)\n  * [row.get](#row-get)\n  * [row.getId](#row-getId)\n  * [row.linksTo](#row-linksTo)\n  * [row.linkedBy](#row-linkedBy)\n  * [row.relatesTo](#row-relatesTo)\n\n<a name=\"new-DB\"/>\n### new DB(conf)\n\nPlease refer to the the [connection pool conf](https://github.com/felixge/node-mysql#pooling-connections) in mysql package for the config format.\n\n__Example__\n\n```javascript\nvar box = new DB({\n    host     : 'localhost',\n    user     : 'root',\n    password : '',\n    database : 'prod_clone'\n});\n```\n\n<a name=\"db-connect\">\n### db.connect(procedure, callback)\n\nThe procedure is a function of the type: \n\n```javascript\nfunction(connection, callback) {\n    // work with the database connection \n}\n```\n\n__Example__\n\n```javascript\nvar basicTest = function(cb) {\n    box.connect(function(conn, cb) {\n        cps.seq([\n            function(_, cb) {\n                conn.query('select * from users limit 1', cb);\n            },\n            function(res, cb) {\n                console.log(res);\n                cb();\n            }\n        ], cb);\n    }, cb);\n};\n```\n\n<a name=\"db-transaction\"/>\n### db.transaction(db_connection, procedure, callback)\n\nThe procedure is a function of the type: \n\n```javascript\nfunction(connection, callback) {\n    // work with the database connection \n}\n```\n\nNote that db.transaction takes one more arguemnt than the db.connect,\nwhich is a database connection object.  If this connection object is\nalready a transactional, then it will be used directly in the provided\nprocedure.  Otherwise, the connection will be \"made transactional\" and\nthen used in the provided procedure.\n\n__Example__\n\n```javascript\nvar txnTest = function(cb) {\n    var add2Rows = function(conn, b, cb) {\n        dw.transaction(\n            conn/*This is a non-transactional connection.*/, \n            function(\n                conn/*A new transactional connection is \n                      created to handle the transactional session.*/, \n                cb\n            ) {\n                cps.seq([\n                    function(_, cb) {\n                        Model.Table.create(conn, getSampleDto(), cb);\n                    },\n                    function(_, cb) {\n                        dw.transaction(\n                            conn/*This is already a transactional connection.*/, \n                            function(\n                                conn/*No new transactional connection created. \n                                      This connection is the same one as \n                                      in the calling context*/, \n                                cb\n                            ) {\n                                console.log(conn.__transaction__)\n                                Model.Table.create(conn, getSampleDto(), cb);\n                            }, \n                            cb\n                        );\n                    },\n                    function(_, cb) {\n                        if (b) {\n                            cb(null, \"Commit\");\n                        } else {\n                            throw new Error(\"Roll back\");\n                        }\n                    }\n                ], cb);\n            }, \n            cb\n        );\n    };\n\n    dw.connect(function(conn, cb) {\n        /* Uncommenting the following line will merge the two calls \n           to add2Rows into one transaction. */\n        // dw.transaction(conn, function(conn, cb) {\n            cps.seq([\n                function(_, cb) {\n                    add2Rows(conn, true, cb);\n                },\n                function(_, cb) {\n                    add2Rows(conn, true, cb);\n                }\n            ], cb);\n        // }, cb);\n    }, cb);\n};\n```\n\n<a name=\"db-cursor\"/>\n### db.cursor(query_string, procedure, callback)\n\nThis API can be used to cursor thought the (potentially very long list\nof) results of a query.  The procedure parameter is the operation to\nbe applied to each row in the results of the query.  Please note the following:\n\n* db.cursor will create a separate db connection for cursoring\n  purpose.  That is why this API does not take a db_connection in the\n  parameter list, unlike most of the other db related APIs.  \n\n* If there is an exception thrown out of the row handling procedure,\n  the cursoring will be stopped and the exception will be thrown out\n  to the top level callback (the 3rd parameter to db.cursor).  If you\n  intend for the cursor to go over all the results, you need to catch\n  any exceptions in the row handling procedure (using cps.rescue).\n\n__Example__\n\n```javascript\n// cursor through all the users and update the active status to \"1\"\nvar cursorTest = function(cb) {\n    db.connect(function(conn, cb) {\n        var q = 'select * from users';\n\n        db.cursor(q, function(row, cb) {\n            cps.rescur({\n                'try': function() {\n                    cps.seq([\n                        function(_, cb) {\n                            var user = new User.Row(row);\n                            user.update(conn, {active: 1}, cb);\n                        }, \n                        function(res, cb) {\n                            console.log(res);\n                            cb();\n                        }\n                    ], cb);\n                },\n                'catch': function(err, cb) {\n                    console.log(err);\n                    cb();\n                }\n            }, cb);\n        }, cb);\n    }, cb);\n};\n```\n\n\n\n\n<a name=\"db-end\" />\n### db.end();\n\nThis function destructs the db object.\n\n<a name=\"db-add\"/>\n\n### db.add(config);\n\nThis function is used to define a model that belongs to the db object.  The model config object is of the following format:\n\n```json\n{\n    \"name\": {\n        \"type\": \"String\",\n        \"description\": \"the name of the table\"\n    },\n    \"idFieldName\": {\n        \"type\": \"String\",\n        \"optional\": true, \n        \"default\": \"id\",\n        \"description\": \"the name of the primary id column\"\n    },\n    \"versionFieldName\": {\n        \"type\": \"String\", \n        \"optional\": true, \n        \"default\": \"version\", \n        \"description\": \"optimistic lock version\"\n    },\n    \"createdFieldName\": {\n        \"type\": \"String\",\n        \"optional\": true, \n        \"default\": \"date_created\",\n        \"description\": \"creation time of the row\"\n    },\n    \"updatedFieldName\": {\n        \"type\": \"String\",\n        \"optional\": true, \n        \"default\": \"last_updated\",\n        \"description\": \"last update time of the row\"\n    },\n    \"Row\": {\n        \"type\": \"Object\",\n        \"optional\": true,\n        \"default\": \"{}\",\n        \"description\": \"the overriding method definition for the Row class of this model\"\n    },\n    \"Table\": {\n        \"type\": \"Object\",\n        \"optional\": true,\n        \"default\": \"{}\",\n        \"description\": \"the overriding method definition for the Table class of this model\"\n    }\n}\n```\n\nNote that db.add returns a Table object, which can be further chained\nwith linking/joining functions such as [linksTo](#table-linksTo),\n[linkedBy](#table-linkedBy) and [relatesTo](#table-relatesTo).\n\n__Example__\n\n```javascript\ndb.add({\n    name: 'orders',\n    idFieldName: 'order_id',\n    Row: {\n        getFirstOrderItem: function(conn, cb) {\n            var me = this;\n\n            cps.seq([\n                function(_, cb) {\n                    me.linkedBy(conn, 'items', cb);\n                },\n                function(items, cb) {\n                    cb(null, items[0]);\n                }\n            ], cb);\n        }\n    },\n    Table: {\n        createOrderUsingCoupon: function(conn, dto, coupon, cb) {\n            dto['coupon_id'] = coupon.getId();\n            this.create(conn, dto, cb);\n        }\n    }\n})\n    .linkedBy({\n        name: 'items',\n        key: 'order_id',\n        table: 'order_items'\n    })\n    .linksTo({\n        name: 'user',\n        key: 'user_id',\n        table: 'users'\n    })\n    .linksTo({\n        name: 'coupon',\n        key: 'coupon_id',\n        table: 'coupons'\n    })\n    .linksTo({\n        name: 'credit_card',\n        key: 'credit_card_id',\n        table: 'credit_cards'\n    })\n;\n\n```\n\nIn this example: \n\n* We created a model for the table \"orders\" in the database.  \n* We add a method getFirstOrderItem into the Row class of this model.\n* We add a method createOrderWithCoupon into the Table class of this model.\n* We follow the foreign key relations of the \"orders\" table to define some link relations.\n\n<a name=\"db-get\"/>\n\n### db.get(table_name)\n\nOnce you use db.add to create a model in the db object, you can then\nuse db.get to retrieve it by name.  The return value of\ndb.get if a object of the following format:\n\n```json\n{\n    \"Row\": {\n        \"type\": \"Row object\"\n    },\n    \"Table\": {\n        \"type\": \"Table object\"\n    }\n}\n```\n\n__Example__\n\n```javascript\nvar Order = db.get('orders');\nvar Coupon = db.get('coupons');\n\ndb.connect(function(conn, cb) {\n    cps.seq([\n        function(_, cb) {\n            Coupon.Table.findByCode(conn, '10-percent-off', cb);\n        }\n        function(coupon, cb) {\n            var dto = {/*dto data*/};\n            Order.createOrderWithCoupon(conn, dto, coupon, cb);\n        },\n        function(order, cb) {\n            order.getFirstOrderItem(conn, cb);\n        },\n        function(firstItem, cb) {\n            console.log(firstItem);\n            cb()\n        }\n    ], cb);\n}, cb);\n```\n\n\n<a name=\"DB-format\" />\n### DB.format(query_string, variable_bindings)\n\nThis is a wrapper of the query string formatting functionality\nprovided by the mysql package.  Note that this is a global static\nmethod defined on the class DB.  It is NOT an instance method defined\na a DB instance db.\n\n__Example__\n\n```javascript\nDB.format('select * from users where id = ?' [userId]);\n```\n<a name=\"new-Table\"/>\n### new Table(table_config)\n\nThe table config schema is defined as follows:\n\n```json\n{\n    \"name\": {\n        \"type\": \"String\",\n        \"optional\": false,\n        \"description\": \"the name of the database table\"\n    },\n    \"idFieldName\": {\n        \"type\": \"String\",\n        \"optional\": true, \n        \"default\": \"id\",\n        \"description\": \"the name of the primary id column\"\n    },\n    \"versionFieldName\": {\n        \"type\": \"String\", \n        \"optional\": true, \n        \"default\": \"version\", \n        \"description\": \"optimistic lock version\"\n    },\n    \"createdFieldName\": {\n        \"type\": \"String\",\n        \"optional\": true, \n        \"default\": \"date_created\",\n        \"description\": \"creation time of the row\"\n    },\n    \"updatedFieldName\": {\n        \"type\": \"String\",\n        \"optional\": true, \n        \"default\": \"last_updated\",\n        \"description\": \"last update time of the row\"\n    },\n    \"rowClass\": {\n        \"type\": \"Row class\",\n        \"optional\": false,\n        \"description\": \"the Row class of this table\"\n    },\n    \"db\": {\n        \"type\": \"DB class instance\",\n        \"optional\": false,\n        \"description\": \"the DB instance that the table belongs to\"\n    }   \n}\n```\n\nSee [here](#row-table-instantiation) for an example of creating a table.  \n\n\n<a name=\"table-create\"/>\n\n### table.create(database_connection, data_object, callback)\n\nThe callback here takes a Row object as result.\n\n__Example__\n\n```javascript\nvar createTest = function(cb) {\n    dw.connect(function(conn, cb) {\n        cps.seq([\n            function(_, cb) {\n                User.Table.create(conn, {\n                    first_name: 'Hannah',\n                    last_name: 'Mckay',\n                    gender: 'female'\n                    // ....\n                }, cb);\n            },\n            function(user, cb) {  // user is an object of the class User.Row\n                console.log(user.get('first_name')); // print out 'Hannah'\n                cb();\n            }\n        ], cb);\n    }, cb);\n};\n```\n\nIn the input data object, please do NOT specify the following fields:\n\n* primary ID\n* date_created\n* last_udpated\n* version\n\nAll of the these fields will be filled by the invocation to table.create.\n\n\n<a name=\"table-clone\"/>\n\n### table.clone(database_connection, data_object, callback)\n\nThis API is very similar to table.create.  The key difference is that\nit does not mask out any data field carried in data_object.  Instead,\nit literally uses every thing in data_object to create a new row.  In\nother words, it'll honor the values of the following fields in\ndata_object:\n\n* primary ID\n* date_created\n* last_udpated\n* version\n\nThis API can be useful when one attempts to clone a row in a table\nliterally to another table (which might be in another database).\n\n<a name=\"table-find\"/>\n### table.find(database_connection, query_string, callback)\n\nThis function is not too different from doing a query directly on a\ndatabase connection.  The only extra thing it does is to turn the\nresult from a list of simple hash objects to a list of Row objects of\nthe corresponding table's \"rowClass\".\n\n__Example__\n\n```javascript\ndw.connect(function(conn, cb) {\n    var o;\n    cps.seq([\n        function(_, cb) {\n            User.Table.find(conn, 'select * from users', cb);\n        },\n        function(users, cb) { // users is a list of user object of the class User.Row\n            console.log(users[0]);  // print the information of the first user\n            cb();\n        }\n    ], cb);\n}, cb);\n```\n\n<a name=\"table-findById\"/>\n### table.findById(database_connection, row_id, callback)\n\nThis is simply a short-hand for:\n\n```javascript\ncps.seq([\n    function(_, cb) {\n        table.find(\n            conn, \n            DB.format('select * from table_name where primary_id = ?', [row_id]),\n            cb\n        );\n    },\n    function(res, cb) {\n        cb(res[0]);\n    }\n], cb);\n```\n\nIt finds a row in a table by its primary ID and returns a single row\nobject of the table's corresponding rowClass.\n\n<a name=\"table-lockById\"/>\n### table.lockById(database_connection, row_id, callback)\n\nThis function does the same thing as findById and additionally, it\nlocks the corresponding row for an atomic update.  lockById can ONLY\nbe used in a transaction context.  Without a transaction context, it\nbehaves the same as findById.  Once a row is locked in one\ntransaction, attempts of locking the same row in other transactions\nwill hang until the current transaction either commits or rolls back,\nwhich release the current lock.\n\n__Example__\n\n```javascript\nvar lockTest = function(cb) {\n    var exclusiveUpdate = function(conn, delay, value, cb) {\n        dw.transaction(null, function(conn, cb) {\n            cps.seq([\n                function(_, cb) {\n                    Model.Table.lockById(conn, 1, cb);\n                },\n                function(res, cb) {\n                    setTimeout(function() {\n                        cb(null, res);\n                    }, delay);\n                },\n                function(row, cb) {\n                    row.update(conn, {'subscription_status': value}, cb);\n                },\n                function(res, cb) {\n                    cb();\n                }\n            ], cb)\n        }, cb);\n\n    };\n\n    var conn;\n\n    dw.transaction(conn, function(conn, cb) {\n        cps.seq([\n            function(_, cb) {\n                cps.parallel([\n                    function(cb) {\n                        exclusiveUpdate(conn, 2000, 'foo1', cb);\n                    },\n                    function(cb) {\n                        exclusiveUpdate(conn, 0, 'bar1', cb);\n                    }\n                ], cb);\n            },\n            function(res, cb) {\n                console.log(res);\n                cb();\n            }\n        ], cb);\n    }, cb);\n};\n```\n\nIn this example, two threads are executed in parallel.  The thread of\nsetting value \"bar1\" will be block by the thread of setting value\n\"foo1\".\n\n<a name=\"table-findAll\"/>\n### table.findAll(database_connection, callback)\n\nThis finds all the rows in a table.\n\n<a name=\"table-baseQuery\"/>\n### table.baseQuery(query_string, variable_bindings)\n\nThis is a short-hand for:\n\n```javascript\nDB.format('select * from table_name' + query_string, variable_bindings);\n```\n\nIt simply prepend a partial string indicating from which table the\nquery is being performed.  This might come handy in many cases.\n\n<a name=\"table-linksTo\"/>\n### table.linksTo(config)\n\nThe config object has the following schema:\n\n```json\n{\n    \"name\": {\n        \"type\": \"String\",\n        \"description\": \"The name of the field to add to the row's data.\"\n    },\n    \"key\": {\n        \"type\": \"String\",\n        \"description\": \"The key that belongs to the current table and links to another table.\"\n    },\n    \"table\": {\n        \"type\": \"String\",\n        \"description\": \"The name of the table that the current table links to.\"\n    }\n}\n```\n\n__Example__\n\n```javascript\n    Order.Table\n        .linksTo({\n            name: 'credit_card',\n            key: 'credit_card_id'\n            table: 'credit_cards'\n        })\n        .linksTo({\n            name: 'shipping_address',\n            key: 'shipping_address_id'\n            table: 'addresses'\n        })\n    ;\n```\n\nNote that for \"linksTo\", the (join) key is on the current table.  Once\na \"linksTo\" is set up, a row object that corresponds to this table can\ncall the \"linksTo\" method to pull more (associated) data into the row.\nSee examples [here](#row-linksTo).\n\n<a name=\"table-linkedBy\"/>\n### table.linkedBy(config)\n\nThe config object has the following schema:\n\n```json\n{\n    \"name\": {\n        \"type\": \"String\",\n        \"description\": \"The name of the field to add to the row's data.\"\n    },\n    \"key\": {\n        \"type\": \"String\",\n        \"description\": \"The key that belongs to the other table and links to the current table.\"\n    },\n    \"table\": {\n        \"type\": \"String\",\n        \"description\": \"The name of the table that the current table is linked by.\"\n    }\n}\n```\n\n__Example__\n\n```javascript\n    Order.Table\n        .linkedBy({\n            name: 'items',\n            table: OrderItem.Table,\n            key: 'order_id'\n        })\n    ;\n```\n\nOnce a \"linkedBy\" is set up on a table, a row object corresponding to\nthis table can call the \"linkedBy\" method to pull more (associated)\ndata into the row.  See examples [here](#row-linkedBy).\n\n<a name=\"table-relatesTo\"/>\n\n### table.relatesTo(config)\n\nThe config object has the following schema:\n\n```json\n{\n    \"name\": {\n        \"type\": \"String\",\n        \"description\": \"The name of the field to add to the row's data.\"\n    },\n    \"through\": {\n        \"type\": \"String\",\n        \"description\": \"The name of the through table, which joins both the current table and the target table.\"\n    },\n    \"leftKey\": {\n        \"type\": \"String\",\n        \"description\": \"The key that belongs to the current table and joins with the through table.\"\n    },\n    \"table\": {\n        \"type\": \"String\",\n        \"description\": \"The name of the target table that the current table is joining thourgh the through-table.\"\n    },\n    \"rightKey\": {\n        \"type\": \"String\",\n        \"description\": \"The key that belongs to the target table and joins with the through table.\"\n    }\n}\n```\n\n__Example__\n\n```javascript\n    Order.Table\n        .relatesTo({\n            name: 'coupons',\n            leftKey: 'order_id',\n            through: 'order_coupons',\n            rightKey: 'coupon_id',\n            table: 'coupons'\n        })\n    ;\n```\n\ntable.relatesTo is designed to represent ORM of a many-to-many\nrelation.  Once a \"relatesTo\" is set up on a table, a row object\ncorresponding to this table can call the \"relatesTo\" method to pull\nmore (associated) data into the row.  See examples\n[here](#row-relatesTo).\n\n<a name=\"new-Row\" />\n### new Row(row_data)\n\nAfter having a concrete Row class, row instances can be created using\nit.  The row_data parameter is an object mapping database table column\nnames to their corresponding values.\n\n__Example__\n\n```javascript\nnew User.Row({\n    first_name: 'Hannah',\n    last_name: 'Mckay',\n    gender: 'female'\n    //....\n});\n```\n<a name=\"row-update\"/>\n\n### row.update(database_connection, update_object, callback)\n\nThis function will set the following column automatically:\n\n* last_updated.  This field will be set to the present time stamp.\n* version.  This field will be increased.\n\nOther than these columns, only columns listed in the update_object will be updated.\n\n__Example__\n\n```javascript\nvar findAndUpdateTest = function(cb) {\n    dw.connect(function(conn, cb) {\n        cps.seq([\n            function(_, cb) {\n                User.Table.findById(conn, id, cb);\n            },\n            function(user, cb) {\n                var dto = {\n                    'last_name': 'Morgan'\n                };\n                user.update(conn, dto, cb);\n            }\n        ], cb);\n    }, cb);\n};\n```\n\n<a name=\"row-updateWithoutOptimisticLock\"/>\n### row.updateWithoutOptimisticLock(database_connection, update_object, callback)\n\nThis function is the same as row.update with only one difference: it\ndoes not care about the optimistic lock version field.  It neither\nlooks at this field nor update field.  This might be useful\nocasionally when optimistic lock functionality needs to be overriden.\n\n\n<a name=\"row-get\"/>\n### row.get(column_name)\n\nGet the value of a certain column from the row object.\n\n<a name=\"row-getId\"/>\n### row.getId()\n\nGet the primary ID of the row object.\n\n<a name=\"row-linksTo\"/>\n### row.linksTo(database_connection, field_name, callback)\n\nGiven a \"linksTo\" setup in the corresponding \"Table\" object, row.linksTo pulls further relevant data into the row.\n\n__Example__\n\n```javascript\nvar order;\n\ncps.seq([\n    function(_, cb) {\n        Order.Table.findById(conn, id, cb);\n    },\n    function(res, cb) {\n        order = res;\n        order.linksTo(conn, 'credit_card', cb);\n    },\n    function(_, cb) {\n        order.linksTo(conn, 'shipping_address', cb);\n    },\n    function(_, cb) {\n        console.log(order.get('credit_card').getId());\n        console.log(order.get('shipping_address').getId());\n        cb();\n    }\n], cb);\n```\n\n<a name=\"row-linkedBy\"/>\n### row.linkedBy(database_connection, field_name, callback)\n\nGiven a \"linkedBy\" setup in the corresponding \"Table\" object, row.linkedBy pulls further relevant data into the row.\n\n__Example__\n\n```javascript\nvar order;\n\ncps.seq([\n    function(_, cb) {\n        Order.Table.findById(conn, id, cb);\n    },\n    function(res, cb) {\n        order = res;\n        order.linkedBy(conn, 'items', cb);\n    },\n    function(items, cb) {\n        // items will both be bound to the return value and be assigned to the 'items' field.\n        console.log(items);\n        console.log(order.get('items'));\n        cb();\n    }\n], cb);\n```\n\n<a name=\"row-relatesTo\"/>\n### row.relatesTo(database_connection, field_name, callback)\n\nGiven a \"relatesTo\" setup in the corresponding \"Table\" object, row.relatesTo pulls further relevant data into the row.\n\n__Example__\n\n```javascript\nvar order;\n\ncps.seq([\n    function(_, cb) {\n        Order.Table.findById(conn, id, cb);\n    },\n    function(res, cb) {\n        order = res;\n        order.relatesTo(conn, 'coupons', cb);\n    },\n    function(coupons, cb) {\n        // coupons will both be bound to the return value and be assigned to the 'coupons' field.\n        console.log(coupons); \n        console.log(order.get('coupons'));\n        cb();\n    }\n], cb);\n```\n",
  "readmeFilename": "README.md",
  "homepage": "https://github.com/redblaze/node-mysql",
  "_id": "node-mysql@0.3.4",
  "dist": {
    "shasum": "118f7e3d5fa939d56fbb8f41b39ce5c7ef3f2023"
  },
  "_from": "node-mysql@",
  "_resolved": "https://registry.npmjs.org/node-mysql/-/node-mysql-0.3.4.tgz"
}
