diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f326d5..8b3467d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## Unreleased +### Changed +- `insert` returns ID inserted. +- `save` returns ID inserted / updated. + ## [1.3.2] - 2019-08-08 ### Fixed - Updated `@janiscommerce/query-builder` version diff --git a/README.md b/README.md index 81e0655..4a32c18 100644 --- a/README.md +++ b/README.md @@ -45,13 +45,13 @@ const config = { - `model`: a Model instance with the *database*, *tables*, *fields*, *joins* and other data. - `item`: *type* `OBJECT`, the object to be inserted. - - **Returns**, `boolean` if the object was inserted correctly returns `true`. + - **Returns**, `ID` of the object inserted. * `save(model, item)` **ASYNCHRONOUS**, Saved an individual object in the database. Duplicate Objects updates it. - `model`: a Model instance with the *database*, *tables*, *fields*, *joins* and other data. - `item`: *type* `OBJECT`,the object to be saved. - - **Returns**, `Promise` with `true` if the object was saved correctly. + - **Returns**, `ID` of the object inserted / updated. * `multiInsert(model, items)` **ASYNCHRONOUS**, Performs an Insert of multiple objects. Duplicate Objects updates it. @@ -151,7 +151,7 @@ movieItem = { try { movieResponse = await mysql.insert(movieModel, movieItem); - // Response: TRUE + // Response: 1 console.log('Movie Saved'); // Print in Console } catch (error) { console.log('These Movie can\'t be saved.'); @@ -208,7 +208,7 @@ movieItem = { try { movieResponse = await mysql.save(movieModel, movieItem); - // Insert and Response: TRUE + // Insert and Response: 2 console.log('Movie Saved'); // Print in Console } catch(error) { diff --git a/lib/mysql.js b/lib/mysql.js index 3fde116..0e9e6e5 100644 --- a/lib/mysql.js +++ b/lib/mysql.js @@ -83,7 +83,7 @@ class MySQL { * Insert an item into the database * @param {instance} model - Model instance * @param {object} item - The item to insert - * @returns {Promise} True if success + * @returns {Insert} ID */ async insert(model, item) { @@ -98,8 +98,9 @@ class MySQL { const queryBuilder = new QueryBuilder(this.knex, model); // Insert could response with an Array with 0 value if Primary Key is not AutoIncremental // or Primary Key value if is ID and Integer and AutoIncremental - const result = await queryBuilder.insert(item); - return !!result; + const [result] = await queryBuilder.insert(item); + + return result || item.id; } catch(error) { throw new MySQLError(error.message, MySQLError.codes.INVALID_INSERT); @@ -111,7 +112,7 @@ class MySQL { * Save a new items or update it in the SQL database. * @param {instance} model Model Class Instance * @param {object} item object to saved - * @returns {Promise} True if success + * @returns {Integer} ID */ async save(model, item) { @@ -125,7 +126,8 @@ class MySQL { const queryBuilder = new QueryBuilder(this.knex, model); const [result] = await queryBuilder.save(item); - return !!result[this.constructor.affectedRows]; + // If ID is not Auto-Incremental 'insertId0 is 0 when insert. Anything else 'insertId' is ID inserted + return result.insertId || item.id; } catch(error) { throw new MySQLError(error.message, MySQLError.codes.INVALID_SAVE); diff --git a/tests/mysql-test.js b/tests/mysql-test.js index c934339..0ddd425 100644 --- a/tests/mysql-test.js +++ b/tests/mysql-test.js @@ -52,18 +52,53 @@ describe('MySQL module', function() { sandbox.restore(); }); - it('should return true if try to insert a new Item', async function() { + it('should return ID if try to insert a new Item with no Auto-Incremental ID', async function() { + + const item = { + id: 1, + superhero: 'superman' + }; sandbox.stub(QueryBuilder.prototype, 'insert').callsFake(() => { - return [0]; + return [0]; // Knex return this if no auto-incremental ID }); - const result = await mysql.insert(dummyModel, { - id: 1, - superhero: 'superman' + const result = await mysql.insert(dummyModel, item); + + assert.strictEqual(result, item.id); + }); + + it('should return ID if try to insert a new Item with Auto-Incremental ID', async function() { + + const itemIdGenerated = 10; + + const item = { + superhero: 'supergirl' + }; + + sandbox.stub(QueryBuilder.prototype, 'insert').callsFake(() => { + return [itemIdGenerated]; // Knex return this if no auto-incremental ID }); - assert.equal(result, true); + const result = await mysql.insert(dummyModel, item); + + assert.strictEqual(result, itemIdGenerated); + }); + + it('should return ID if try to insert a new Item which has ID with Auto-Incremental ID', async function() { + + const item = { + id: 20, + superhero: 'Wolverine' + }; + + sandbox.stub(QueryBuilder.prototype, 'insert').callsFake(() => { + return [item.id]; // Knex return this if no auto-incremental ID + }); + + const result = await mysql.insert(dummyModel, item); + + assert.strictEqual(result, item.id); }); it('should throw MySqlError if try to insert an item that already exist', async function() { @@ -78,24 +113,48 @@ describe('MySQL module', function() { await assert.rejects(mysql.insert(dummyModel, item), { code: MySQLError.codes.INVALID_INSERT }); }); - it('should return true if try to save a new item', async function() { + it('should return ID if try to save a new item with ID no auto-incremental', async function() { + + const item = { + id: 2, + superhero: 'batman' + }; sandbox.stub(QueryBuilder.prototype, 'save').callsFake(() => { return [{ affectedRows: 1, insertId: 0 }]; }); - const result = await mysql.save(dummyModel, { - id: 2, + const result = await mysql.save(dummyModel, item); + + assert.strictEqual(result, item.id); + }); + + it('should return ID if try to save a new item with ID auto-incremental', async function() { + + const itemIDGenerated = 2; + + const item = { superhero: 'batman' + }; + + sandbox.stub(QueryBuilder.prototype, 'save').callsFake(() => { + return [{ affectedRows: 1, insertId: itemIDGenerated }]; }); - assert.equal(result, true); + const result = await mysql.save(dummyModel, item); + + assert.strictEqual(result, itemIDGenerated); }); - it('should return true if try to save an old item', async function() { + it('should return ID if try to save an existing item', async function() { + + const item = { + id: 1, + superhero: 'hulk' + }; sandbox.stub(QueryBuilder.prototype, 'save').callsFake(() => { - return [{ affectedRows: 2 }]; + return [{ affectedRows: 2, insertId: item.id }]; }); const result = await mysql.save(dummyModel, { @@ -103,7 +162,7 @@ describe('MySQL module', function() { superhero: 'hulk' }); - assert.equal(result, true); + assert.strictEqual(result, item.id); }); @@ -120,7 +179,7 @@ describe('MySQL module', function() { const result = await mysql.update(dummyModel, fields, filters); - assert.equal(result, 2); + assert.strictEqual(result, 2); }); it('should return 0 if try to update using filters don\'t match any item', async function() { @@ -136,7 +195,7 @@ describe('MySQL module', function() { const result = await mysql.update(dummyModel, fields, filters); - assert.equal(result, 0); + assert.strictEqual(result, 0); }); it('should return 1 if try to multi-Insert a new Item', async function() { @@ -151,7 +210,7 @@ describe('MySQL module', function() { }]); - assert.equal(result, 1); + assert.strictEqual(result, 1); }); it('should return the quantity of new items as rows affected if try to multi-Insert new Items', async function() { @@ -167,7 +226,7 @@ describe('MySQL module', function() { ]); - assert.equal(result, 3); + assert.strictEqual(result, 3); }); it('should return the double of quantity of new items as rows affected if try to multi-Insert Items which already exist', async function() { @@ -182,7 +241,7 @@ describe('MySQL module', function() { ]); - assert.equal(result, 4); + assert.strictEqual(result, 4); }); }); @@ -314,7 +373,7 @@ describe('MySQL module', function() { }); const testParams = (params, expectedParams) => { - assert.deepEqual(params, expectedParams, 'shouldn\'t modify ofiginal params'); + assert.deepStrictEqual(params, expectedParams, 'shouldn\'t modify ofiginal params'); }; it('should return default values getting totals with empty tables', async function() { @@ -328,7 +387,7 @@ describe('MySQL module', function() { total: 0 }; - assert.deepEqual(await mysql.getTotals(dummyModel), totalExpected); + assert.deepStrictEqual(await mysql.getTotals(dummyModel), totalExpected); }); it('Should return empty results and totals with zero values', async function() { @@ -339,11 +398,11 @@ describe('MySQL module', function() { const result = await mysql.get(dummyModel, params); - assert.deepEqual(result, []); + assert.deepStrictEqual(result, []); const resultTotals = await mysql.getTotals(dummyModel); - assert.deepEqual(resultTotals, { total: 0, pages: 0 }); + assert.deepStrictEqual(resultTotals, { total: 0, pages: 0 }); testParams(params, {}); }); @@ -357,7 +416,7 @@ describe('MySQL module', function() { const result = await mysql.get(dummyModel, params); - assert.deepEqual(result, [{ result: 1 }, { result: 2 }]); + assert.deepStrictEqual(result, [{ result: 1 }, { result: 2 }]); testParams(params, originalParams); @@ -365,7 +424,7 @@ describe('MySQL module', function() { const resultTotals = await mysql.getTotals(dummyModel); - assert.deepEqual(resultTotals, { + assert.deepStrictEqual(resultTotals, { total: 650, page: 1, pageSize: 500, @@ -382,7 +441,7 @@ describe('MySQL module', function() { const result = await mysql.get(dummyModel, params); - assert.deepEqual(result, [{ result: 1 }, { result: 2 }]); + assert.deepStrictEqual(result, [{ result: 1 }, { result: 2 }]); testParams(params, originalParams); @@ -390,7 +449,7 @@ describe('MySQL module', function() { const resultTotals = await mysql.getTotals(dummyModel); - assert.deepEqual(resultTotals, { + assert.deepStrictEqual(resultTotals, { total: 650, page: 4, pageSize: 10, @@ -407,7 +466,7 @@ describe('MySQL module', function() { const result = await mysql.get(dummyModel, params); - assert.deepEqual(result, [{ result: 1 }, { result: 2 }]); + assert.deepStrictEqual(result, [{ result: 1 }, { result: 2 }]); testParams(params, originalParams); @@ -415,7 +474,7 @@ describe('MySQL module', function() { const resultTotals = await mysql.getTotals(dummyModel); - assert.deepEqual(resultTotals, { + assert.deepStrictEqual(resultTotals, { total: 650, page: 65, pageSize: 10, @@ -483,7 +542,7 @@ describe('MySQL module', function() { filters: { id: 1 } }); - assert.equal(results, 1); + assert.strictEqual(results, 1); }); it('should throw MySqlError if can not remove', async function() {