msnodesqlv8
Version:
Microsoft Driver for Node.js SQL Server compatible with all versions of Node.
483 lines (428 loc) • 11.4 kB
JavaScript
'use strict'
const { userModule } = require('./user')
const utilModule = require('./util').utilModule
const userTypes = new userModule.SqlTypes()
const splitter = new utilModule.SchemaSplitter()
/*
use a concrete type to represent a table column
when binding to a table based on row fetched from
the metadata query.
*/
/*
ordinal_position: 2,
table_catalog: "",
table_schema: "dbo",
table_name: "test_default_val_table_bulk",
column_default: "('def1')",
name: "s1",
type: "varchar",
max_length: 255,
precision: 0,
scale: 0,
is_nullable: false,
is_computed: false,
is_identity: false,
object_id: 2137696055,
generated_always_type: 0,
generated_always_type_desc: "NOT_APPLICABLE",
is_hidden: 0,
is_primary_key: 0,
is_foreign_key: 0,
*/
class UserTypeColumn {
constructor (name, type, declaration, scale, precision, offset, maxLength) {
let length = 0
if (maxLength > 0) {
if (type === 'nvarchar') {
length = maxLength / 2
} else if (type === 'varbinary') {
length = maxLength
} else {
length = maxLength
}
}
this.name = name
this.userType = declaration
this.scale = scale
this.precision = precision
this.type = {
offset,
declaration: type,
length
}
}
}
class TableColumn {
constructor (tableName, tableSchema, ordinalPosition, columnName, type, maxLength, isPrimaryKey) {
if (!columnName) return
columnName = splitter.stripEscape(columnName)
this.table_name = tableName
this.table_schema = tableSchema
this.name = columnName
this.type = type
this.max_length = maxLength
this.is_primary_key = isPrimaryKey
this.ordinal_position = ordinalPosition
this.table_catalog = ''
this.column_default = ''
this.precision = 0
this.scale = 0
this.is_nullable = false
this.is_computed = false
this.is_identity = false
this.object_id = 0
this.generated_always_type = 0
this.generated_always_type_desc = 'NOT_APPLICABLE'
this.is_hidden = 0
this.is_foreign_key = 0
this.decorator = ''
this.sql_type = this.getDelcaredType()
}
getDelcaredType () {
return userTypes.getSqlTypeFromDeclaredType(this).sql_type
}
static asTableColumn (rawCol) {
const tp = new TableColumn()
tp.fromRaw(rawCol)
return tp
}
isReadOnly () {
return (this.is_identity ||
this.is_computed ||
this.is_hidden ||
this.generated_always_type ||
this.type === 'timestamp')
}
isTzAdjusted () {
return this.type === 'datetimeoffset' ||
this.type === 'datetime' ||
this.type === 'datetime2' ||
this.type === 'time' ||
this.type === 'date' ||
this.type === 'smalldatetime'
}
asUserType (useUTC) {
const declaration = `${this.typed(true)}`
let offset = 0
const isDateTime = this.isTzAdjusted()
if (useUTC === false && isDateTime) {
offset = new Date().getTimezoneOffset()
}
return new UserTypeColumn(this.name, this.type, declaration, this.scale, this.precision, offset, this.max_length)
}
procTyped () {
return this.typed(false, false)
}
isOne () {
return this.type === 'float' ||
this.type === 'binary' ||
this.type === 'varbinary' ||
this.type === 'varchar' ||
this.type === 'nvarchar' ||
this.type === 'nchar' ||
this.type === 'char'
}
isTwo () {
return this.type === 'numeric' ||
this.type === 'decimal' ||
this.type === 'time'
}
maxLength () {
let maxLength = this.max_length || 0
if (this.type === 'nvarchar' || this.type === 'nchar') {
if (maxLength === -1) {
maxLength = 'MAX'
} else {
maxLength = maxLength / 2
}
}
return maxLength
}
typed (user, withDecorator) {
const decorator = withDecorator ? this.decorator : ''
const oneParam = this.isOne()
const twoParam = this.isTwo()
const timeParam =
this.type === 'time'
const maxLength = this.maxLength()
if (this.is_computed) {
return user ? `${this.type}` : `${decorator}`
} else if (timeParam) {
return `${this.type} (${this.scale}) ${decorator}`
} else if (oneParam) {
return `${this.type} (${maxLength}) ${decorator}`
} else if (twoParam) {
return `${this.type} (${this.precision},${this.scale}) ${decorator}`
} else {
return `${this.type} ${decorator}`
}
}
fromRaw (c) {
this.table_name = c.table_name
this.table_schema = c.table_schema
this.name = c.name
this.type = c.type
this.sql_type = this.getDelcaredType()
this.max_length = c.max_length
this.is_primary_key = c.is_primary_key
this.ordinal_position = c.ordinal_position
this.table_catalog = c.table_catalog
this.column_default = c.column_default
this.precision = c.precision
this.scale = c.scale
this.is_nullable = c.is_nullable
this.is_computed = c.is_computed
this.is_identity = c.is_identity
this.object_id = c.object_id
this.generated_always_type = c.generated_always_type
this.generated_always_type_desc = c.generated_always_type_desc
this.is_hidden = c.is_hidden
this.is_foreign_key = c.is_foreign_key
this.decorator = ''
}
asExpression (expression) {
this.is_computed = true
this.decorator = expression
return this
}
isComputed (v) {
this.is_computed = v
return this
}
isIdentity (v, start, inc) {
start = start || 1
this.is_identity = v
if (v) {
inc = inc || 1
this.decorator = `IDENTITY(${start},${inc})`
}
return this
}
isHidden (v) {
this.is_hidden = v
return this
}
isPrimaryKey (v) {
this.is_primary_key = v
return this
}
isForeignKey (v) {
this.is_foreign_key = v
return this
}
notNull () {
this.withDecorator('NOT NULL')
return this
}
null () {
this.withDecorator('NULL')
return this
}
withDecorator (v) {
if (this.decorator !== null && this.decorator.length > 0) {
this.decorator += ' ' + v
} else {
this.decorator = v
}
return this
}
asBit () {
this.type = 'bit'
this.sql_type = this.getDelcaredType()
this.max_length = 1
this.precision = 1
this.scale = 0
return this
}
asInt () {
this.type = 'int'
this.sql_type = this.getDelcaredType()
this.length = 4
this.precision = 10
this.scale = 0
return this
}
asNVarCharMax () {
return this.asNVarChar(-1)
}
asNVarChar (length) {
length = length || 56
this.type = 'nvarchar'
this.sql_type = this.getDelcaredType()
this.max_length = length > 0 ? length * 2 : length
this.precision = length > 0 ? length : 0
this.scale = 0
return this
}
asBinary (length) {
this.type = 'binary'
this.sql_type = this.getDelcaredType()
this.max_length = length
this.precision = length
this.scale = 0
return this
}
asVarBinary (length) {
this.type = 'varbinary'
this.sql_type = this.getDelcaredType()
this.max_length = length
this.precision = length
this.scale = 0
return this
}
asVarChar (length) {
length = length || 28
this.type = 'varchar'
this.sql_type = this.getDelcaredType()
this.max_length = length
this.precision = length
this.scale = 0
return this
}
asDate () {
this.type = 'date'
this.sql_type = this.getDelcaredType()
this.max_length = 3
this.precision = 10
this.scale = 0
return this
}
asTime (scale) {
this.type = 'time'
this.sql_type = this.getDelcaredType()
this.max_length = 5
this.precision = 16
this.scale = scale || 7
return this
}
asDateTime2 () {
this.type = 'datetime2'
this.sql_type = this.getDelcaredType()
this.max_length = 8
this.precision = 23
this.scale = 3
return this
}
asDateTime () {
this.type = 'datetime'
this.sql_type = this.getDelcaredType()
this.max_length = 8
this.precision = 23
this.scale = 3
return this
}
asDateTimeOffset () {
this.type = 'datetimeoffset'
this.sql_type = this.getDelcaredType()
this.max_length = 10
this.precision = 34
this.scale = 7
return this
}
asMoney () {
this.type = 'money'
this.sql_type = this.getDelcaredType()
this.max_length = 9
this.precision = 10
this.scale = 4
return this
}
asSmallMoney () {
return this.asNumeric(10, 4)
}
asNumeric (precision, scale) {
this.type = 'numeric'
this.sql_type = this.getDelcaredType()
this.max_length = 9
this.precision = precision || 20
this.scale = scale || 15
return this
}
/*
If 1<=n<=24, n is treated as 24. If 25<=n<=53, n is treated as 53.
*/
asFloat (scale) {
scale = scale || 25
this.type = 'float'
this.sql_type = this.getDelcaredType()
this.max_length = scale > 24 ? 8 : 4
this.precision = this.max_length === 4 ? 7 : 15
this.scale = scale
return this
}
asDecimal (precision, scale) {
this.type = 'decimal'
this.sql_type = this.getDelcaredType()
this.max_length = 9
this.precision = precision || 23
this.scale = scale || 18
return this
}
asUniqueIdentifier () {
this.type = 'uniqueidentifier'
this.sql_type = this.getDelcaredType()
this.max_length = 16
this.precision = 36
this.scale = 0
return this
}
asHierarchyId () {
this.type = 'hierarchyid'
this.sql_type = this.getDelcaredType()
this.max_length = 892
this.precision = 0
this.scale = 0
return this
}
asBigInt () {
this.type = 'bigint'
this.sql_type = this.getDelcaredType()
this.max_length = 8
this.precision = 19
this.scale = 0
return this
}
asSmallInt () {
this.type = 'smallint'
this.sql_type = this.getDelcaredType()
this.max_length = 2
this.precision = 5
this.scale = 0
return this
}
asTinyInt () {
this.type = 'tinyint'
this.sql_type = this.getDelcaredType()
this.max_length = 1
this.precision = 3
this.scale = 0
return this
}
asReal () {
this.type = 'real'
this.sql_type = this.getDelcaredType()
this.max_length = 4
this.precision = 24
this.scale = 0
return this
}
asChar (length) {
length = length || 128
this.type = 'char'
this.sql_type = this.getDelcaredType()
this.max_length = length
this.precision = 0
this.scale = 0
return this
}
asNChar (length) {
length = length || 256
this.type = 'nchar'
this.sql_type = this.getDelcaredType()
this.max_length = length > 0 ? length * 2 : length
this.precision = 0
this.scale = 0
return this
}
}
exports.TableColumn = TableColumn