-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
298 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
const { expect } = testHelpers; | ||
const types = require( "src/types" ); | ||
|
||
describe( "types", () => { | ||
[ | ||
"bigint", | ||
"bit", | ||
"date", | ||
"datetime", | ||
"image", | ||
"int", | ||
"float", | ||
"money", | ||
"ntext", | ||
"real", | ||
"smalldatetime", | ||
"smallint", | ||
"smallmoney", | ||
"text", | ||
"tvp", | ||
"udt", | ||
"uniqueidentifier", | ||
"variant", | ||
"xml" | ||
].forEach( name => { | ||
it( `should create wrapper for ${ name } type`, () => { | ||
const wrappedType = types[ name ](); | ||
wrappedType.type.name.toLowerCase().should.equal( name ); | ||
} ); | ||
|
||
it( `should declare ${ name } type`, () => { | ||
const wrappedType = types[ name ](); | ||
wrappedType.declaration.should.equal( name ); | ||
} ); | ||
} ); | ||
|
||
describe( "with length", () => { | ||
[ | ||
{ name: "binary", emptyValue: 8000 }, | ||
{ name: "char", emptyValue: 8000 }, | ||
{ name: "nchar", emptyValue: 4000 }, | ||
{ name: "nvarchar", emptyValue: 4000, max: true }, | ||
{ name: "varbinary", emptyValue: 8000, max: true }, | ||
{ name: "varchar", emptyValue: 8000, max: true } | ||
].forEach( ( { name, emptyValue, max } ) => { | ||
describe( name, () => { | ||
it( "should create wrapper with proper type", () => { | ||
const wrappedType = types[ name ]( 1 ); | ||
wrappedType.type.name.toLowerCase().should.equal( name ); | ||
} ); | ||
|
||
it( "should use provided length", () => { | ||
const wrappedType = types[ name ]( 42 ); | ||
wrappedType.length.should.equal( 42 ); | ||
} ); | ||
|
||
it( "should declare type with length", () => { | ||
const wrappedType = types[ name ]( 42 ); | ||
wrappedType.declaration.should.equal( `${ name }(42)` ); | ||
} ); | ||
|
||
it( "should use default length", () => { | ||
const wrappedType = types[ name ](); | ||
wrappedType.length.should.equal( emptyValue ); | ||
} ); | ||
|
||
it( "should declare type with default length", () => { | ||
const wrappedType = types[ name ](); | ||
wrappedType.declaration.should.equal( `${ name }(${ emptyValue })` ); | ||
} ); | ||
|
||
if ( max ) { | ||
it( "should use max length", () => { | ||
const wrappedType = types[ name ]( types.max ); | ||
expect( wrappedType.length ).to.be.null(); | ||
wrappedType.max.should.equal( true ); | ||
} ); | ||
|
||
it( "should declare type with max length", () => { | ||
const wrappedType = types[ name ]( types.max ); | ||
wrappedType.declaration.should.equal( `${ name }(max)` ); | ||
} ); | ||
|
||
it( `should have ${ name }_max type`, () => { | ||
const wrappedType = types[ `${ name }_max` ]; | ||
expect( wrappedType.length ).to.be.null(); | ||
wrappedType.max.should.equal( true ); | ||
} ); | ||
|
||
it( `should declare type ${ name }_max with max length`, () => { | ||
const wrappedType = types[ `${ name }_max` ]; | ||
wrappedType.declaration.should.equal( `${ name }(max)` ); | ||
} ); | ||
} | ||
} ); | ||
} ); | ||
} ); | ||
|
||
describe( "with scale", () => { | ||
[ | ||
{ name: "datetime2", emptyValue: 7 }, | ||
{ name: "datetimeoffset", emptyValue: 7 }, | ||
{ name: "time", emptyValue: 7 } | ||
].forEach( ( { name, emptyValue } ) => { | ||
describe( name, () => { | ||
it( "should create wrapper with proper type", () => { | ||
const wrappedType = types[ name ]( 1 ); | ||
wrappedType.type.name.toLowerCase().should.equal( name ); | ||
} ); | ||
|
||
it( "should use provided scale", () => { | ||
const wrappedType = types[ name ]( 5 ); | ||
wrappedType.scale.should.equal( 5 ); | ||
} ); | ||
|
||
it( "should declare type with scale", () => { | ||
const wrappedType = types[ name ]( 42 ); | ||
wrappedType.declaration.should.equal( `${ name }(42)` ); | ||
} ); | ||
|
||
it( "should use default scale", () => { | ||
const wrappedType = types[ name ](); | ||
wrappedType.scale.should.equal( emptyValue ); | ||
} ); | ||
|
||
it( "should declare type with default scale", () => { | ||
const wrappedType = types[ name ]( ); | ||
wrappedType.declaration.should.equal( `${ name }(${ emptyValue })` ); | ||
} ); | ||
} ); | ||
} ); | ||
} ); | ||
|
||
describe( "with precision and scale", () => { | ||
[ | ||
{ name: "decimal", emptyPrecision: 18, emptyScale: 0 }, | ||
{ name: "numeric", emptyPrecision: 18, emptyScale: 0 } | ||
].forEach( ( { name, emptyPrecision, emptyScale } ) => { | ||
describe( name, () => { | ||
it( "should create wrapper with proper type", () => { | ||
const wrappedType = types[ name ]( 2, 1 ); | ||
wrappedType.type.name.toLowerCase().should.equal( name ); | ||
} ); | ||
|
||
it( "should use provided precision and scale", () => { | ||
const wrappedType = types[ name ]( 5, 1 ); | ||
wrappedType.precision.should.equal( 5 ); | ||
wrappedType.scale.should.equal( 1 ); | ||
} ); | ||
|
||
it( "should declare type with precision and scale", () => { | ||
const wrappedType = types[ name ]( 5, 1 ); | ||
wrappedType.declaration.should.equal( `${ name }(5,1)` ); | ||
} ); | ||
|
||
it( "should use defaults", () => { | ||
const wrappedType = types[ name ](); | ||
wrappedType.precision.should.equal( emptyPrecision ); | ||
wrappedType.scale.should.equal( emptyScale ); | ||
} ); | ||
|
||
|
||
it( "should declare type with default precision and scale", () => { | ||
const wrappedType = types[ name ](); | ||
wrappedType.declaration.should.equal( `${ name }(${ emptyPrecision },${ emptyScale })` ); | ||
} ); | ||
} ); | ||
} ); | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,44 @@ | ||
module.exports = class TypeWrapper { | ||
const max = Symbol( "skwell:max" ); | ||
|
||
class TypeWrapper { | ||
|
||
constructor( type, opts ) { | ||
this.type = type; | ||
|
||
if ( opts ) { | ||
Object.keys( opts ).forEach( k => { | ||
this[ k ] = opts[ k ]; | ||
} ); | ||
} | ||
if ( this.length === max ) { | ||
this.length = null; | ||
this.max = true; | ||
} | ||
} | ||
|
||
nullable( val = true ) { | ||
this.isNull = val; | ||
return this; | ||
} | ||
|
||
}; | ||
get declaration() { | ||
const typeName = this.type.name.toLowerCase(); | ||
if ( this.hasOwnProperty( "length" ) ) { | ||
const val = this.max ? "max" : this.length; | ||
return `${ typeName }(${ val })`; | ||
} else if ( this.hasOwnProperty( "precision" ) && this.hasOwnProperty( "scale" ) ) { | ||
return `${ typeName }(${ this.precision },${ this.scale })`; | ||
} else if ( this.hasOwnProperty( "scale" ) ) { | ||
return `${ typeName }(${ this.scale })`; | ||
} | ||
return typeName; | ||
} | ||
|
||
static get max() { | ||
return max; | ||
} | ||
|
||
} | ||
|
||
|
||
module.exports = TypeWrapper; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,53 @@ | ||
/* eslint-disable camelcase */ | ||
/* eslint-disable no-magic-numbers */ | ||
const { TYPES } = require( "tedious" ); | ||
|
||
const TypeWrapper = require( "./TypeWrapper" ); | ||
const { max } = TypeWrapper; | ||
|
||
module.exports = | ||
Object.keys( TYPES ).reduce( ( acc, name ) => { | ||
if ( name.endsWith( "N" ) || name === "Null" ) { | ||
// Stop deprecated type warnings from tedious. | ||
return acc; | ||
} | ||
const type = TYPES[ name ]; | ||
const key = name.toLowerCase(); | ||
const types = { | ||
binary: ( length = 8000 ) => new TypeWrapper( TYPES.Binary, { length } ), | ||
bigint: () => new TypeWrapper( TYPES.BigInt ), | ||
bit: () => new TypeWrapper( TYPES.Bit ), | ||
char: ( length = 8000 ) => new TypeWrapper( TYPES.Char, { length } ), | ||
date: () => new TypeWrapper( TYPES.Date ), | ||
datetime: () => new TypeWrapper( TYPES.DateTime ), | ||
datetime2: ( scale = 7 ) => new TypeWrapper( TYPES.DateTime2, { scale } ), | ||
datetimeoffset: ( scale = 7 ) => new TypeWrapper( TYPES.DateTimeOffset, { scale } ), | ||
decimal: ( precision = 18, scale = 0 ) => new TypeWrapper( TYPES.Decimal, { precision, scale } ), | ||
image: () => new TypeWrapper( TYPES.Image ), | ||
int: () => new TypeWrapper( TYPES.Int ), | ||
float: () => new TypeWrapper( TYPES.Float ), | ||
money: () => new TypeWrapper( TYPES.Money ), | ||
nchar: ( length = 4000 ) => new TypeWrapper( TYPES.NChar, { length } ), | ||
ntext: () => new TypeWrapper( TYPES.NText ), | ||
nvarchar: ( length = 4000 ) => new TypeWrapper( TYPES.NVarChar, { length } ), | ||
numeric: ( precision = 18, scale = 0 ) => new TypeWrapper( TYPES.Numeric, { precision, scale } ), | ||
real: () => new TypeWrapper( TYPES.Real ), | ||
smalldatetime: () => new TypeWrapper( TYPES.SmallDateTime ), | ||
smallint: () => new TypeWrapper( TYPES.SmallInt ), | ||
smallmoney: () => new TypeWrapper( TYPES.SmallMoney ), | ||
text: () => new TypeWrapper( TYPES.Text ), | ||
time: ( scale = 7 ) => new TypeWrapper( TYPES.Time, { scale } ), | ||
tvp: () => new TypeWrapper( TYPES.TVP ), | ||
udt: () => new TypeWrapper( TYPES.UDT ), | ||
uniqueidentifier: () => new TypeWrapper( TYPES.UniqueIdentifier ), | ||
varbinary: ( length = 8000 ) => new TypeWrapper( TYPES.VarBinary, { length } ), | ||
varchar: ( length = 8000 ) => new TypeWrapper( TYPES.VarChar, { length } ), | ||
variant: () => new TypeWrapper( TYPES.Variant ), | ||
xml: () => new TypeWrapper( TYPES.Xml ) | ||
}; | ||
|
||
if ( type.maximumLength ) { | ||
acc[ key ] = length => new TypeWrapper( type, { length } ); | ||
} else if ( type.hasPrecision && type.hasScale ) { | ||
acc[ key ] = ( precision, scale ) => new TypeWrapper( type, { precision, scale } ); | ||
} else if ( type.hasScale ) { | ||
acc[ key ] = scale => new TypeWrapper( type, { scale } ); | ||
} else { | ||
acc[ key ] = () => new TypeWrapper( type ); | ||
} | ||
Object.keys( types ).forEach( key => { | ||
types[ key ].nullable = function( val ) { | ||
return types[ key ]().nullable( val ); | ||
}; | ||
} ); | ||
|
||
acc[ key ].nullable = function( val ) { | ||
return acc[ key ]().nullable( val ); | ||
}; | ||
|
||
return acc; | ||
}, { max: null } ); | ||
module.exports = { | ||
...types, | ||
varbinary_max: types.varbinary( max ), | ||
varchar_max: types.varchar( max ), | ||
nvarchar_max: types.nvarchar( max ), | ||
max | ||
}; |