Skip to content

Commit

Permalink
feat: support insert multi rows
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed Jun 7, 2015
1 parent cad4612 commit abb4804
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 17 deletions.
70 changes: 63 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,60 @@ var db = rds({
});
```

### Queries
### Insert

- Query with arguments
- Insert one row

```js
var rows = yield db.query('SELECT * FROM your_table LIMIT 100');
console.log(rows);
var row = {
name: 'fengmk2',
otherField: 'other field value',
createdAt: db.literals.now, // `now()` on db server
// ...
};
var result = yield db.insert('table-name', row);
console.log(result);
{ fieldCount: 0,
affectedRows: 1,
insertId: 3710,
serverStatus: 2,
warningCount: 2,
message: '',
protocol41: true,
changedRows: 0 }
```

- Query with arguments
- Insert multi rows

Will execute under a transaction and auto commit.

```js
var rows = yield db.query('SELECT * FROM your_table WHERE id=?', [123]);
console.log(rows);
var rows = [
{
name: 'fengmk1',
otherField: 'other field value',
createdAt: db.literals.now, // `now()` on db server
// ...
},
{
name: 'fengmk2',
otherField: 'other field value',
createdAt: db.literals.now, // `now()` on db server
// ...
},
// ...
];

var results = yield db.insert('table-name', rows);
console.log(result);
{ fieldCount: 0,
affectedRows: 2,
insertId: 3840,
serverStatus: 2,
warningCount: 2,
message: '&Records: 2 Duplicates: 0 Warnings: 0',
protocol41: true,
changedRows: 0 }
```

### Transactions
Expand Down Expand Up @@ -101,6 +141,22 @@ try {
}
```

### Raw Queries

- Query with arguments

```js
var rows = yield db.query('SELECT * FROM your_table LIMIT 100');
console.log(rows);
```

- Query with arguments

```js
var rows = yield db.query('SELECT * FROM your_table WHERE id=?', [123]);
console.log(rows);
```

## SQL Server Usage

TBD
Expand Down
8 changes: 6 additions & 2 deletions lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,18 @@ proto._query = function (sql) {
proto.beginTransaction = function () {
var conn = this.conn;
return function (callback) {
conn.beginTransaction(callback);
conn.beginTransaction(function (err, result) {
callback(err, result);
});
};
};

proto.commit = function () {
var conn = this.conn;
return function (callback) {
conn.commit(callback);
conn.commit(function (err, result) {
callback(err, result);
});
};
};

Expand Down
34 changes: 26 additions & 8 deletions lib/operator.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ proto.select = function* (table, options) {
this._where(options.where) +
this._orders(options.orders) +
this._limit(options.limit, options.offset);
debug('list(%j, %j) \n=> %j', table, options, sql);
debug('select(%j, %j) \n=> %j', table, options, sql);
return yield this.query(sql);
};

Expand All @@ -83,17 +83,35 @@ proto.get = function* (table, where, options) {
return rows && rows[0] || null;
};

proto.insert = function* (table, obj, options) {
proto.insert = function* (table, rows, options) {
options = options || {};
var firstObj;
// insert(table, rows)
if (Array.isArray(rows)) {
firstObj = rows[0];
} else {
// insert(table, row)
firstObj = rows;
rows = [rows];
}
if (!options.columns) {
options.columns = Object.keys(obj);
options.columns = Object.keys(firstObj);
}
var values = [];
for (var i = 0; i < options.columns.length; i++) {
values.push(obj[options.columns[i]]);

var params = [table, options.columns];
var strs = [];
for (var i = 0; i < rows.length; i++) {
var values = [];
var row = rows[i];
for (var j = 0; j < options.columns.length; j++) {
values.push(row[options.columns[j]]);
}
strs.push('(?)');
params.push(values);
}
var sql = this.format('INSERT INTO ??(??) VALUES(?);', [table, options.columns, values]);
debug('insert(%j, %j, %j) \n=> %j', table, obj, options, sql);

var sql = this.format('INSERT INTO ??(??) VALUES' + strs.join(', '), params);
debug('insert(%j, %j, %j) \n=> %j', table, rows, options, sql);
return yield this.query(sql);
};

Expand Down
106 changes: 106 additions & 0 deletions test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var config = require('./config');

describe('client.test.js', function () {
var prefix = 'prefix-' + process.version + '-';
var table = 'ali-sdk-test-user';
before(function* () {
this.db = rds(config);
yield this.db.query('delete from `ali-sdk-test-user` where name like ?', [prefix + '%']);
Expand Down Expand Up @@ -264,6 +265,111 @@ describe('client.test.js', function () {
});
});

describe('insert(table, row[s])', function () {
it('should insert one row', function* () {
var result = yield this.db.insert(table, {
name: prefix + 'fengmk2-insert1',
email: prefix + 'm@fengmk2-insert.com'
});
assert.equal(result.affectedRows, 1);
});

it('should insert multi rows', function* () {
var result = yield this.db.insert(table, [
{
name: prefix + 'fengmk2-insert2',
email: prefix + 'm@fengmk2-insert.com'
},
{
name: prefix + 'fengmk2-insert3',
email: prefix + 'm@fengmk2-insert.com'
},
]);
assert.equal(result.affectedRows, 2);
var row = yield this.db.get(table, {id: result.insertId});
assert(row);
assert.equal(row.id, result.insertId);
});

it('should insert multi fail', function* () {
try {
yield this.db.insert(table, [
{
name: prefix + 'fengmk2-insert4',
email: prefix + 'm@fengmk2-insert.com'
},
{
name: prefix + 'fengmk2-insert4',
email: prefix + 'm@fengmk2-insert.com'
},
]);
throw new Error('should not run this');
} catch (err) {
assert.equal(err.code, 'ER_DUP_ENTRY');
}
var row = yield this.db.get(table, {name: prefix + 'fengmk2-insert4'});
assert(!row);
});

it('should part success on Duplicate key without transaction', function* () {
var result = yield this.db.insert(table, {
name: prefix + 'fengmk2-insert-no-tran',
email: prefix + 'm@fengmk2-insert.com'
});
assert.equal(result.affectedRows, 1);
var rows = yield this.db.select(table, {
where: {name: prefix + 'fengmk2-insert-no-tran'}
});
assert.equal(rows.length, 1);

try {
yield this.db.insert(table, {
name: prefix + 'fengmk2-insert-no-tran',
email: prefix + 'm@fengmk2-insert.com'
});
throw new Error('should not run this');
} catch (err) {
assert.equal(err.code, 'ER_DUP_ENTRY');
}
var rows = yield this.db.select(table, {
where: {name: prefix + 'fengmk2-insert-no-tran'}
});
assert.equal(rows.length, 1);
});

it('should all fail on Duplicate key with transaction', function* () {
var tran = yield this.db.beginTransaction();
try {
var result = yield tran.insert(table, {
name: prefix + 'fengmk2-insert-has-tran',
email: prefix + 'm@fengmk2-insert.com'
});
assert.equal(result.affectedRows, 1);
var rows = yield tran.select(table, {
where: {name: prefix + 'fengmk2-insert-has-tran'}
});
assert.equal(rows.length, 1);

yield tran.insert(table, {
name: prefix + 'fengmk2-insert-has-tran',
email: prefix + 'm@fengmk2-insert.com'
});

yield tran.commit();
} catch (err) {
yield tran.rollback();
assert.equal(err.code, 'ER_DUP_ENTRY');
} finally {
tran.release();
}

var rows = yield this.db.select(table, {
where: {name: prefix + 'fengmk2-insert-has-tran'}
});
assert.equal(rows.length, 0);
});
});

describe('update(table, obj, options)', function () {
before(function* () {
yield this.db.insert('ali-sdk-test-user', {
Expand Down

0 comments on commit abb4804

Please sign in to comment.