不要怂,就是干,撸起袖子干!

Commit c9c00b45 by Jan Aagaard Meier

Merge pull request #4302 from ysagal/add-sqlite-connect-modes

Pass through connection mode options to sqlite
2 parents 9c9b1245 7dcb40a1
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
- [FIXED] Clone the options object in `increment`, `decrement`, `destroy`, `reload`, `restore`, and `save`. [#4023](https://github.com/sequelize/sequelize/pull/4023) - [FIXED] Clone the options object in `increment`, `decrement`, `destroy`, `reload`, `restore`, and `save`. [#4023](https://github.com/sequelize/sequelize/pull/4023)
- [FIXED] Throw a `Sequelize.Error` when `authenticate` fails [#4209](https://github.com/sequelize/sequelize/pull/4209) - [FIXED] Throw a `Sequelize.Error` when `authenticate` fails [#4209](https://github.com/sequelize/sequelize/pull/4209)
- [FIXED] BTM would remove any previously added association getters [#4268](https://github.com/sequelize/sequelize/pull/4268) - [FIXED] BTM would remove any previously added association getters [#4268](https://github.com/sequelize/sequelize/pull/4268)
- [FIXED] Pass through connection mode options to sqlite
[#4288](https://github.com/sequelize/sequelize/issues/4288)
# 3.5.1 # 3.5.1
- [FIXED] Fix bug with nested includes where a middle include results in a null value which breaks $findSeperate. - [FIXED] Fix bug with nested includes where a middle include results in a null value which breaks $findSeperate.
......
...@@ -30,16 +30,25 @@ ConnectionManager.prototype.getConnection = function(options) { ...@@ -30,16 +30,25 @@ ConnectionManager.prototype.getConnection = function(options) {
options.uuid = options.uuid || 'default'; options.uuid = options.uuid || 'default';
options.inMemory = ((self.sequelize.options.storage || self.sequelize.options.host || ':memory:') === ':memory:') ? 1 : 0; options.inMemory = ((self.sequelize.options.storage || self.sequelize.options.host || ':memory:') === ':memory:') ? 1 : 0;
if (self.connections[options.inMemory || options.uuid]) return Promise.resolve(self.connections[options.inMemory || options.uuid]); var dialectOptions = self.sequelize.options.dialectOptions;
options.readWriteMode = dialectOptions && dialectOptions.mode;
if (self.connections[options.inMemory || options.uuid]) {
return Promise.resolve(self.connections[options.inMemory || options.uuid]);
}
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
self.connections[options.inMemory || options.uuid] = new self.lib.Database(self.sequelize.options.storage || self.sequelize.options.host || ':memory:', function(err) { self.connections[options.inMemory || options.uuid] = new self.lib.Database(
if (err) { self.sequelize.options.storage || self.sequelize.options.host || ':memory:',
if (err.code === 'SQLITE_CANTOPEN') return reject(new sequelizeErrors.ConnectionError(err)); options.readWriteMode || (self.lib.OPEN_READWRITE | self.lib.OPEN_CREATE), // default mode
return reject(new sequelizeErrors.ConnectionError(err)); function(err) {
if (err) {
if (err.code === 'SQLITE_CANTOPEN') return reject(new sequelizeErrors.ConnectionError(err));
return reject(new sequelizeErrors.ConnectionError(err));
}
resolve(self.connections[options.inMemory || options.uuid]);
} }
resolve(self.connections[options.inMemory || options.uuid]); );
});
}).tap(function (connection) { }).tap(function (connection) {
if (self.sequelize.options.foreignKeys !== false) { if (self.sequelize.options.foreignKeys !== false) {
// Make it possible to define and use foreign key constraints unless // Make it possible to define and use foreign key constraints unless
......
...@@ -6,7 +6,12 @@ var chai = require('chai') ...@@ -6,7 +6,12 @@ var chai = require('chai')
, config = require(__dirname + '/../config/config') , config = require(__dirname + '/../config/config')
, Support = require(__dirname + '/support') , Support = require(__dirname + '/support')
, dialect = Support.getTestDialect() , dialect = Support.getTestDialect()
, Sequelize = require(__dirname + '/../../index'); , Sequelize = Support.Sequelize
, sqlite3 = require('sqlite3')
, fs = require('fs')
, path = require('path');
describe(Support.getTestDialectTeaser('Configuration'), function() { describe(Support.getTestDialectTeaser('Configuration'), function() {
describe('Connections problems should fail with a nice message', function() { describe('Connections problems should fail with a nice message', function() {
...@@ -107,7 +112,7 @@ describe(Support.getTestDialectTeaser('Configuration'), function() { ...@@ -107,7 +112,7 @@ describe(Support.getTestDialectTeaser('Configuration'), function() {
}); });
}); });
describe('Intantiation with arguments', function() { describe('Instantiation with arguments', function() {
it('should accept two parameters (database, username)', function() { it('should accept two parameters (database, username)', function() {
var sequelize = new Sequelize('dbname', 'root'); var sequelize = new Sequelize('dbname', 'root');
var config = sequelize.config; var config = sequelize.config;
...@@ -142,6 +147,85 @@ describe(Support.getTestDialectTeaser('Configuration'), function() { ...@@ -142,6 +147,85 @@ describe(Support.getTestDialectTeaser('Configuration'), function() {
expect(config.dialectOptions.supportBigNumbers).to.be.true; expect(config.dialectOptions.supportBigNumbers).to.be.true;
expect(config.dialectOptions.bigNumberStrings).to.be.true; expect(config.dialectOptions.bigNumberStrings).to.be.true;
}); });
if (dialect === 'sqlite') {
it('should respect READONLY / READWRITE connection modes', function() {
var p = path.join(__dirname, '../tmp', 'foo.sqlite');
var createTableFoo = 'CREATE TABLE foo (faz TEXT);';
var createTableBar = 'CREATE TABLE bar (baz TEXT);';
var testAccess = Sequelize.Promise.method(function() {
if (fs.access) {
return Sequelize.Promise.promisify(fs.access)(p, fs.R_OK | fs.W_OK);
} else { // Node v0.10 and older don't have fs.access
return Sequelize.Promise.promisify(fs.open)(p, 'r+')
.then(function(fd) {
return Sequelize.Promise.promisify(fs.close)(fd);
});
}
});
return Sequelize.Promise.promisify(fs.unlink)(p)
.catch(function(err) {
expect(err.code).to.equal('ENOENT');
})
.then(function() {
var sequelizeReadOnly = new Sequelize('sqlite://foo', {
storage: p,
dialectOptions: {
mode: sqlite3.OPEN_READONLY
}
});
var sequelizeReadWrite = new Sequelize('sqlite://foo', {
storage: p,
dialectOptions: {
mode: sqlite3.OPEN_READWRITE
}
});
expect(sequelizeReadOnly.config.dialectOptions.mode).to.equal(sqlite3.OPEN_READONLY);
expect(sequelizeReadWrite.config.dialectOptions.mode).to.equal(sqlite3.OPEN_READWRITE);
return Sequelize.Promise.join(
sequelizeReadOnly.query(createTableFoo)
.should.be.rejectedWith(Error, 'SQLITE_CANTOPEN: unable to open database file'),
sequelizeReadWrite.query(createTableFoo)
.should.be.rejectedWith(Error, 'SQLITE_CANTOPEN: unable to open database file')
);
})
.then(function() {
// By default, sqlite creates a connection that's READWRITE | CREATE
var sequelize = new Sequelize('sqlite://foo', {
storage: p
});
return sequelize.query(createTableFoo);
})
.then(testAccess)
.then(function() {
var sequelizeReadOnly = new Sequelize('sqlite://foo', {
storage: p,
dialectOptions: {
mode: sqlite3.OPEN_READONLY
}
});
var sequelizeReadWrite = new Sequelize('sqlite://foo', {
storage: p,
dialectOptions: {
mode: sqlite3.OPEN_READWRITE
}
});
return Sequelize.Promise.join(
sequelizeReadOnly.query(createTableBar)
.should.be.rejectedWith(Error, 'SQLITE_READONLY: attempt to write a readonly database'),
sequelizeReadWrite.query(createTableBar)
);
})
.finally(function() {
return Sequelize.Promise.promisify(fs.unlink)(p);
});
});
}
}); });
}); });
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!