it('does not leak variables to the outer scope',asyncfunction(){
it('does not leak variables to the outer scope',asyncfunction(){
// This is a little tricky. We want to check the values in the outer scope, when the transaction has been successfully set up, but before it has been comitted.
// This is a little tricky. We want to check the values in the outer scope, when the transaction has been successfully set up, but before it has been comitted.
...
@@ -100,8 +99,8 @@ if (current.dialect.supports.transactions) {
...
@@ -100,8 +99,8 @@ if (current.dialect.supports.transactions) {
expect(this.ns.get('transaction')).not.to.be.ok;
expect(this.ns.get('transaction')).not.to.be.ok;
});
});
it('does not leak outside findOrCreate',function(){
it('does not leak outside findOrCreate',asyncfunction(){
returnthis.User.findOrCreate({
awaitthis.User.findOrCreate({
where:{
where:{
name:'Kafka'
name:'Kafka'
},
},
...
@@ -110,26 +109,25 @@ if (current.dialect.supports.transactions) {
...
@@ -110,26 +109,25 @@ if (current.dialect.supports.transactions) {
thrownewError('The transaction was not properly assigned');
thrownewError('The transaction was not properly assigned');
}
}
}
}
}).then(()=>{
returnthis.User.findAll();
});
});
awaitthis.User.findAll();
});
});
});
});
describe('sequelize.query integration',()=>{
describe('sequelize.query integration',()=>{
it('automagically uses the transaction in all calls',function(){
it('automagically uses the transaction in all calls',asyncfunction(){
someProperty:Sequelize.VIRTUAL,// Since we specify the AS part as a part of the literal string, not with sequelize syntax, we have to tell sequelize about the field
someProperty:Sequelize.VIRTUAL,// Since we specify the AS part as a part of the literal string, not with sequelize syntax, we have to tell sequelize about the field
it('uses properties `query` and `values` if query is tagged',function(){
it('uses properties `query` and `values` if query is tagged',asyncfunction(){
letlogSql;
letlogSql;
returnthis.sequelize.query({query:'select ? as foo, ? as bar',values:[1,2]},{type:this.sequelize.QueryTypes.SELECT,logging(s){logSql=s;}}).then(result=>{
constresult=awaitthis.sequelize.query({query:'select ? as foo, ? as bar',values:[1,2]},{type:this.sequelize.QueryTypes.SELECT,logging(s){logSql=s;}});
expect(result).to.deep.equal([{foo:1,bar:2}]);
expect(result).to.deep.equal([{foo:1,bar:2}]);
expect(logSql).to.not.include('?');
expect(logSql).to.not.include('?');
});
});
});
it('uses properties `query` and `bind` if query is tagged',function(){
it('uses properties `query` and `bind` if query is tagged',asyncfunction(){
consttypeCast=dialect==='postgres'?'::int':'';
consttypeCast=dialect==='postgres'?'::int':'';
letlogSql;
letlogSql;
returnthis.sequelize.query({query:`select $1${typeCast} as foo, $2${typeCast} as bar`,bind:[1,2]},{type:this.sequelize.QueryTypes.SELECT,logging(s){logSql=s;}}).then(result=>{
constresult=awaitthis.sequelize.query({query:`select $1${typeCast} as foo, $2${typeCast} as bar`,bind:[1,2]},{type:this.sequelize.QueryTypes.SELECT,logging(s){logSql=s;}});
it('replaces named parameters with the passed object using the same key twice',function(){
it('replaces named parameters with the passed object using the same key twice',asyncfunction(){
returnexpect(this.sequelize.query('select :one as foo, :two as bar, :one as baz',{raw:true,replacements:{one:1,two:2}}).then(obj=>obj[0]))
awaitexpect(this.sequelize.query('select :one as foo, :two as bar, :one as baz',{raw:true,replacements:{one:1,two:2}}).then(obj=>obj[0]))
.to.eventually.deep.equal([{foo:1,bar:2,baz:1}]);
.to.eventually.deep.equal([{foo:1,bar:2,baz:1}]);
});
});
it('replaces named parameters with the passed object having a null property',function(){
it('replaces named parameters with the passed object having a null property',asyncfunction(){
returnexpect(this.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:{one:1,two:null}}).then(obj=>obj[0]))
awaitexpect(this.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:{one:1,two:null}}).then(obj=>obj[0]))
.to.eventually.deep.equal([{foo:1,bar:null}]);
.to.eventually.deep.equal([{foo:1,bar:null}]);
});
});
it('reject when key is missing in the passed object',function(){
it('reject when key is missing in the passed object',asyncfunction(){
returnthis.sequelize.query('select :one as foo, :two as bar, :three as baz',{raw:true,replacements:{one:1,two:2}})
awaitthis.sequelize.query('select :one as foo, :two as bar, :three as baz',{raw:true,replacements:{one:1,two:2}})
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
});
});
it('reject with the passed number',function(){
it('reject with the passed number',asyncfunction(){
returnthis.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:2})
awaitthis.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:2})
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
});
});
it('reject with the passed empty object',function(){
it('reject with the passed empty object',asyncfunction(){
returnthis.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:{}})
awaitthis.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:{}})
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
});
});
it('reject with the passed string',function(){
it('reject with the passed string',asyncfunction(){
returnthis.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:'foobar'})
awaitthis.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:'foobar'})
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
});
});
it('reject with the passed date',function(){
it('reject with the passed date',asyncfunction(){
returnthis.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:newDate()})
awaitthis.sequelize.query('select :one as foo, :two as bar',{raw:true,replacements:newDate()})
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
.should.be.rejectedWith(Error,/Named parameter ":\w+" has no value in the given object\./g);
});
});
it('binds token with the passed array',function(){
it('binds token with the passed array',asyncfunction(){
consttypeCast=dialect==='postgres'?'::int':'';
consttypeCast=dialect==='postgres'?'::int':'';
letlogSql;
letlogSql;
returnthis.sequelize.query(`select $1${typeCast} as foo, $2${typeCast} as bar`,{type:this.sequelize.QueryTypes.SELECT,bind:[1,2],logging(s){logSql=s;}}).then(result=>{
constresult=awaitthis.sequelize.query(`select $1${typeCast} as foo, $2${typeCast} as bar`,{type:this.sequelize.QueryTypes.SELECT,bind:[1,2],logging(s){logSql=s;}});
expect(result).to.deep.equal([{foo:1,bar:2}]);
expect(result).to.deep.equal([{foo:1,bar:2}]);
if(dialect==='postgres'||dialect==='sqlite'){
if(dialect==='postgres'||dialect==='sqlite'){
expect(logSql).to.include('$1');
expect(logSql).to.include('$1');
}
}
});
});
});
it('binds named parameters with the passed object',function(){
it('binds named parameters with the passed object',asyncfunction(){
consttypeCast=dialect==='postgres'?'::int':'';
consttypeCast=dialect==='postgres'?'::int':'';
letlogSql;
letlogSql;
returnthis.sequelize.query(`select $one${typeCast} as foo, $two${typeCast} as bar`,{raw:true,bind:{one:1,two:2},logging(s){logSql=s;}}).then(result=>{
constresult=awaitthis.sequelize.query(`select $one${typeCast} as foo, $two${typeCast} as bar`,{raw:true,bind:{one:1,two:2},logging(s){logSql=s;}});
it('binds named parameters with the passed object using the same key twice',function(){
it('binds named parameters with the passed object using the same key twice',asyncfunction(){
consttypeCast=dialect==='postgres'?'::int':'';
consttypeCast=dialect==='postgres'?'::int':'';
letlogSql;
letlogSql;
returnthis.sequelize.query(`select $one${typeCast} as foo, $two${typeCast} as bar, $one${typeCast} as baz`,{raw:true,bind:{one:1,two:2},logging(s){logSql=s;}}).then(result=>{
constresult=awaitthis.sequelize.query(`select $one${typeCast} as foo, $two${typeCast} as bar, $one${typeCast} as baz`,{raw:true,bind:{one:1,two:2},logging(s){logSql=s;}});
returnthis.sequelize.query(`SELECT ${datetime} AS t`).then(([result])=>{
const[result]=awaitthis.sequelize.query(`SELECT ${datetime} AS t`);
expect(moment(result[0].t).isValid()).to.be.true;
expect(moment(result[0].t).isValid()).to.be.true;
});
});
});
if(Support.getTestDialect()==='postgres'){
if(Support.getTestDialect()==='postgres'){
it('replaces named parameters with the passed object and ignores casts',function(){
it('replaces named parameters with the passed object and ignores casts',asyncfunction(){
returnexpect(this.sequelize.query('select :one as foo, :two as bar, \'1000\'::integer as baz',{raw:true,replacements:{one:1,two:2}}).then(obj=>obj[0]))
awaitexpect(this.sequelize.query('select :one as foo, :two as bar, \'1000\'::integer as baz',{raw:true,replacements:{one:1,two:2}}).then(obj=>obj[0]))
returnexpect(this.sequelize.query('WITH RECURSIVE t(n) AS ( VALUES (1) UNION ALL SELECT n+1 FROM t WHERE n < 100) SELECT sum(n) FROM t').then(obj=>obj[0]))
awaitexpect(this.sequelize.query('WITH RECURSIVE t(n) AS ( VALUES (1) UNION ALL SELECT n+1 FROM t WHERE n < 100) SELECT sum(n) FROM t').then(obj=>obj[0]))
.to.eventually.deep.equal([{'sum':'5050'}]);
.to.eventually.deep.equal([{'sum':'5050'}]);
});
});
}
}
if(Support.getTestDialect()==='sqlite'){
if(Support.getTestDialect()==='sqlite'){
it('binds array parameters for upsert are replaced. $$ unescapes only once',function(){
it('binds array parameters for upsert are replaced. $$ unescapes only once',asyncfunction(){
letlogSql;
letlogSql;
returnthis.sequelize.query('select $1 as foo, $2 as bar, \'$$$$\' as baz',{type:this.sequelize.QueryTypes.UPSERT,bind:[1,2],logging(s){logSql=s;}}).then(()=>{
awaitthis.sequelize.query('select $1 as foo, $2 as bar, \'$$$$\' as baz',{type:this.sequelize.QueryTypes.UPSERT,bind:[1,2],logging(s){logSql=s;}});
// sqlite.exec does not return a result
// sqlite.exec does not return a result
expect(logSql).to.not.include('$one');
expect(logSql).to.not.include('$one');
expect(logSql).to.include('\'$$\'');
expect(logSql).to.include('\'$$\'');
});
});
});
it('binds named parameters for upsert are replaced. $$ unescapes only once',function(){
it('binds named parameters for upsert are replaced. $$ unescapes only once',asyncfunction(){
letlogSql;
letlogSql;
returnthis.sequelize.query('select $one as foo, $two as bar, \'$$$$\' as baz',{type:this.sequelize.QueryTypes.UPSERT,bind:{one:1,two:2},logging(s){logSql=s;}}).then(()=>{
awaitthis.sequelize.query('select $one as foo, $two as bar, \'$$$$\' as baz',{type:this.sequelize.QueryTypes.UPSERT,bind:{one:1,two:2},logging(s){logSql=s;}});
@@ -161,28 +166,27 @@ if (current.dialect.supports.transactions) {
...
@@ -161,28 +166,27 @@ if (current.dialect.supports.transactions) {
/commit has been called on this transaction\([^)]+\), you can no longer use it\.\(The rejected query is attached as the 'sql' property of this error\)/
/commit has been called on this transaction\([^)]+\), you can no longer use it\.\(The rejected query is attached as the 'sql' property of this error\)/