diff --git a/README.md b/README.md index cd1ef3fafa..5b86bce697 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,9 @@ Root URL (localhost:3000/) returns all REST API urls for each table in schema. ## CRUD APIs Usual Suspects * GET       /api/tableName * POST      /api/tableName +* PUT       /api/tableName ( acts as REPLACE ) * GET       /api/tableName/:id -* PUT       /api/tableName/:id +* PATCH       /api/tableName/:id ( acts as UPDATE ) * GET       /api/tableName/findOne * GET       /api/tableName/count * GET       /api/tableName/:id/exists diff --git a/assets/log.gif b/assets/log.gif index 210d361cef..e3be0cc0b5 100644 Binary files a/assets/log.gif and b/assets/log.gif differ diff --git a/lib/util/cmd.helper.js b/lib/util/cmd.helper.js index cee0b42a16..ece6868de9 100644 --- a/lib/util/cmd.helper.js +++ b/lib/util/cmd.helper.js @@ -11,7 +11,7 @@ program.on('--help', () => { }) program - .version('0.2.3') + .version('0.2.4') .option('-h, --host ', 'hostname') .option('-d, --database ', 'database schema name') .option('-u, --user ', 'username of database / root by default') diff --git a/lib/xapi.js b/lib/xapi.js index 9e22448136..0e2b8bd03d 100644 --- a/lib/xapi.js +++ b/lib/xapi.js @@ -112,7 +112,6 @@ class Xapi { /**************** START : setup routes for each table ****************/ - let resources = []; resources = this.mysql.getSchemaRoutes(true, '/api/'); @@ -150,6 +149,11 @@ class Xapi { .get(this.asyncMiddleware(this.read.bind(this))); break; + case 'patch': + this.app.route(routes[i]['routeUrl']) + .patch(this.asyncMiddleware(this.patch.bind(this))); + break; + case 'update': this.app.route(routes[i]['routeUrl']) .put(this.asyncMiddleware(this.update.bind(this))); @@ -246,6 +250,7 @@ class Xapi { } + /** * * @param req @@ -412,8 +417,22 @@ class Xapi { } + async update(req, res) { + let query = 'REPLACE INTO ?? SET ?'; + let params = []; + + params.push(req.app.locals._tableName); + params.push(req.body); + + var results = await this.mysql.exec(query, params); + res.status(200).json(results); + + } + + async patch(req, res) { + let query = 'UPDATE ?? SET '; let keys = Object.keys(req.body); @@ -449,6 +468,44 @@ class Xapi { } + + // async update(req, res) { + // + // let query = 'UPDATE ?? SET '; + // let keys = Object.keys(req.body); + // + // // SET clause + // let updateKeys = ''; + // for (let i = 0; i < keys.length; ++i) { + // updateKeys += keys[i] + ' = ? ' + // if (i !== keys.length - 1) + // updateKeys += ', ' + // } + // + // // where clause + // query += updateKeys + ' where ' + // let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, + // req.params.id.split('___')); + // + // if (!clause) { + // return res.status(400).send({ + // error: "Table is made of composite primary keys - all keys were not in input" + // }) + // } + // + // query += clause; + // + // // params + // let params = []; + // params.push(req.app.locals._tableName); + // params = params.concat(Object.values(req.body)); + // + // let results = await this.mysql.exec(query, params); + // res.status(200).json(results); + // + // + // } + async delete(req, res) { let query = 'DELETE FROM ?? WHERE '; diff --git a/lib/xsql.js b/lib/xsql.js index f19e37f973..f9d3b0a5ca 100644 --- a/lib/xsql.js +++ b/lib/xsql.js @@ -462,8 +462,9 @@ class Xsql { routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/findOne', 'findOne')) routes.push(this.prepareRoute(internal, 'post', apiPrefix, tableName, 'create')) routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName, 'list')) + routes.push(this.prepareRoute(internal, 'put', apiPrefix, tableName, 'update')) routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/:id', 'read')) - routes.push(this.prepareRoute(internal, 'put', apiPrefix, tableName + '/:id', 'update')) + routes.push(this.prepareRoute(internal, 'patch', apiPrefix, tableName + '/:id', 'patch')) routes.push(this.prepareRoute(internal, 'delete', apiPrefix, tableName + '/:id', 'delete')) routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/:id/exists', 'exists')) diff --git a/package.json b/package.json index 223681a601..8a4146ef28 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xmysql", - "version": "0.2.3", + "version": "0.2.4", "description": "One command to generate REST APIs for any MySql database", "main": "index.js", "scripts": { diff --git a/tests/tests.js b/tests/tests.js index f5bcc78126..7ba690b52f 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -455,8 +455,36 @@ describe('xmysql : tests', function () { return done(); }); + }); + + it('PUT /api/productlines should PASS', function (done) { + + var obj = {}; + obj['productLine'] = 'Hyperloop' + obj['textDescription'] = 'Hyperloop is essentially a train system that ElonMusk calls \"a cross between ' + + 'a Concorde, a railgun, and an air hockey table\". ' + + 'It\'s based on the very high-speed transit (VHST) system proposed in 1972,' + + 'which combines a magnetic levitation train and a low pressure transit tube.' + + 'It evolves some of the original ideas of VHST, but it still uses tunnels' + + 'and pods or capsules to move from place to place.' + //post to an url with data + agent.put('/api/productlines') //enter url + .send(obj) //postdata + .expect(200)//200 for success 4xx for failure + .end(function (err, res) { + // Handle /api/v error + if (err) { + return done(err); + } + + //validate response + res.body['affectedRows'].should.be.equals(2) + + return done(); + + }); }); it('POST /dynamic should PASS', function (done) { @@ -477,7 +505,6 @@ describe('xmysql : tests', function () { } //validate response - res.body.length.should.be.equals(5) return done(); @@ -537,7 +564,9 @@ describe('xmysql : tests', function () { }); }); - it('PUT /api/customers/:id should PASS', function (done) { + + + it('PATCH /api/productlines/Hyperloop should PASS', function (done) { var obj = {}; @@ -549,7 +578,7 @@ describe('xmysql : tests', function () { 'and pods or capsules to move from place to place.' //post to an url with data - agent.put('/api/productlines/Hyperloop') //enter url + agent.patch('/api/productlines/Hyperloop') //enter url .send(obj) //postdata .expect(200)//200 for success 4xx for failure .end(function (err, res) {