Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
public
/
sequelize
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
不要怂,就是干,撸起袖子干!
Commit e01cc2f8
authored
Sep 26, 2017
by
Michael Kaufman
Committed by
Sushant
Sep 26, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(postgres/date): support for infinity timestamp (#8357)
1 parent
45457b00
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
516 additions
and
43 deletions
lib/data-types.js
lib/dialects/postgres/data-types.js
lib/model.js
test/integration/data-types.test.js
test/integration/dialects/postgres/data-types.test.js
test/integration/model/geography.test.js
lib/data-types.js
View file @
e01cc2f
...
@@ -283,6 +283,27 @@ BOOLEAN.prototype.validate = function validate(value) {
...
@@ -283,6 +283,27 @@ BOOLEAN.prototype.validate = function validate(value) {
return
true
;
return
true
;
};
};
BOOLEAN
.
prototype
.
_sanitize
=
function
_sanitize
(
value
)
{
if
(
value
!==
null
&&
value
!==
undefined
)
{
if
(
Buffer
.
isBuffer
(
value
)
&&
value
.
length
===
1
)
{
// Bit fields are returned as buffers
value
=
value
[
0
];
}
if
(
_
.
isString
(
value
))
{
// Only take action on valid boolean strings.
value
=
value
===
'true'
?
true
:
value
===
'false'
?
false
:
value
;
}
else
if
(
_
.
isNumber
(
value
))
{
// Only take action on valid boolean integers.
value
=
value
===
1
?
true
:
value
===
0
?
false
:
value
;
}
}
return
value
;
};
BOOLEAN
.
parse
=
BOOLEAN
.
prototype
.
_sanitize
;
function
TIME
()
{
function
TIME
()
{
if
(
!
(
this
instanceof
TIME
))
return
new
TIME
();
if
(
!
(
this
instanceof
TIME
))
return
new
TIME
();
}
}
...
@@ -315,6 +336,28 @@ DATE.prototype.validate = function validate(value) {
...
@@ -315,6 +336,28 @@ DATE.prototype.validate = function validate(value) {
return
true
;
return
true
;
};
};
DATE
.
prototype
.
_sanitize
=
function
_sanitize
(
value
,
options
)
{
if
((
!
options
||
options
&&
!
options
.
raw
)
&&
!
(
value
instanceof
Date
)
&&
!!
value
)
{
return
new
Date
(
value
);
}
return
value
;
};
DATE
.
prototype
.
_isChanged
=
function
_isChanged
(
value
,
originalValue
)
{
if
(
originalValue
&&
!!
value
&&
(
value
===
originalValue
||
value
instanceof
Date
&&
originalValue
instanceof
Date
&&
value
.
getTime
()
===
originalValue
.
getTime
()
)
)
{
return
false
;
}
return
true
;
};
DATE
.
prototype
.
_applyTimezone
=
function
_applyTimezone
(
date
,
options
)
{
DATE
.
prototype
.
_applyTimezone
=
function
_applyTimezone
(
date
,
options
)
{
if
(
options
.
timezone
)
{
if
(
options
.
timezone
)
{
if
(
momentTz
.
tz
.
zone
(
options
.
timezone
))
{
if
(
momentTz
.
tz
.
zone
(
options
.
timezone
))
{
...
@@ -350,6 +393,22 @@ DATEONLY.prototype._stringify = function _stringify(date) {
...
@@ -350,6 +393,22 @@ DATEONLY.prototype._stringify = function _stringify(date) {
return
moment
(
date
).
format
(
'YYYY-MM-DD'
);
return
moment
(
date
).
format
(
'YYYY-MM-DD'
);
};
};
DATEONLY
.
prototype
.
_sanitize
=
function
_sanitize
(
value
,
options
)
{
if
(
!
options
||
options
&&
!
options
.
raw
)
{
return
moment
(
value
).
format
(
'YYYY-MM-DD'
);
}
return
value
;
};
DATEONLY
.
prototype
.
_isChanged
=
function
_isChanged
(
value
,
originalValue
)
{
if
(
originalValue
&&
!!
value
&&
originalValue
===
value
)
{
return
false
;
}
return
true
;
};
function
HSTORE
()
{
function
HSTORE
()
{
if
(
!
(
this
instanceof
HSTORE
))
return
new
HSTORE
();
if
(
!
(
this
instanceof
HSTORE
))
return
new
HSTORE
();
}
}
...
...
lib/dialects/postgres/data-types.js
View file @
e01cc2f
...
@@ -34,6 +34,38 @@ module.exports = BaseTypes => {
...
@@ -34,6 +34,38 @@ module.exports = BaseTypes => {
inherits
(
DATEONLY
,
BaseTypes
.
DATEONLY
);
inherits
(
DATEONLY
,
BaseTypes
.
DATEONLY
);
DATEONLY
.
parse
=
function
parse
(
value
)
{
DATEONLY
.
parse
=
function
parse
(
value
)
{
if
(
value
===
'infinity'
)
{
value
=
Infinity
;
}
else
if
(
value
===
'-infinity'
)
{
value
=
-
Infinity
;
}
return
value
;
};
DATEONLY
.
prototype
.
_stringify
=
function
_stringify
(
value
,
options
)
{
if
(
value
===
Infinity
)
{
return
'Infinity'
;
}
else
if
(
value
===
-
Infinity
)
{
return
'-Infinity'
;
}
return
BaseTypes
.
DATEONLY
.
prototype
.
_stringify
.
call
(
this
,
value
,
options
);
};
DATEONLY
.
prototype
.
_sanitize
=
function
_sanitize
(
value
,
options
)
{
if
((
!
options
||
options
&&
!
options
.
raw
)
&&
value
!==
Infinity
&&
value
!==
-
Infinity
)
{
if
(
_
.
isString
(
value
))
{
if
(
_
.
toLower
(
value
)
===
'infinity'
)
{
return
Infinity
;
}
else
if
(
_
.
toLower
(
value
)
===
'-infinity'
)
{
return
-
Infinity
;
}
}
return
BaseTypes
.
DATEONLY
.
prototype
.
_sanitize
.
call
(
this
,
value
);
}
return
value
;
return
value
;
};
};
...
@@ -123,6 +155,27 @@ module.exports = BaseTypes => {
...
@@ -123,6 +155,27 @@ module.exports = BaseTypes => {
return
'BOOLEAN'
;
return
'BOOLEAN'
;
};
};
BOOLEAN
.
prototype
.
_sanitize
=
function
_sanitize
(
value
)
{
if
(
value
!==
null
&&
value
!==
undefined
)
{
if
(
Buffer
.
isBuffer
(
value
)
&&
value
.
length
===
1
)
{
// Bit fields are returned as buffers
value
=
value
[
0
];
}
if
(
_
.
isString
(
value
))
{
// Only take action on valid boolean strings.
value
=
value
===
'true'
||
value
===
't'
?
true
:
value
===
'false'
||
value
===
'f'
?
false
:
value
;
}
else
if
(
_
.
isNumber
(
value
))
{
// Only take action on valid boolean integers.
value
=
value
===
1
?
true
:
value
===
0
?
false
:
value
;
}
}
return
value
;
};
BOOLEAN
.
parse
=
BOOLEAN
.
prototype
.
_sanitize
;
BaseTypes
.
BOOLEAN
.
types
.
postgres
=
{
BaseTypes
.
BOOLEAN
.
types
.
postgres
=
{
oids
:
[
16
],
oids
:
[
16
],
array_oids
:
[
1000
]
array_oids
:
[
1000
]
...
@@ -138,6 +191,40 @@ module.exports = BaseTypes => {
...
@@ -138,6 +191,40 @@ module.exports = BaseTypes => {
return
'TIMESTAMP WITH TIME ZONE'
;
return
'TIMESTAMP WITH TIME ZONE'
;
};
};
DATE
.
prototype
.
validate
=
function
validate
(
value
)
{
if
(
value
!==
Infinity
&&
value
!==
-
Infinity
)
{
return
BaseTypes
.
DATE
.
prototype
.
validate
.
call
(
this
,
value
);
}
return
true
;
};
DATE
.
prototype
.
_stringify
=
function
_stringify
(
value
,
options
)
{
if
(
value
===
Infinity
)
{
return
'Infinity'
;
}
else
if
(
value
===
-
Infinity
)
{
return
'-Infinity'
;
}
return
BaseTypes
.
DATE
.
prototype
.
_stringify
.
call
(
this
,
value
,
options
);
};
DATE
.
prototype
.
_sanitize
=
function
_sanitize
(
value
,
options
)
{
if
((
!
options
||
options
&&
!
options
.
raw
)
&&
!
(
value
instanceof
Date
)
&&
!!
value
&&
value
!==
Infinity
&&
value
!==
-
Infinity
)
{
if
(
_
.
isString
(
value
))
{
if
(
_
.
toLower
(
value
)
===
'infinity'
)
{
return
Infinity
;
}
else
if
(
_
.
toLower
(
value
)
===
'-infinity'
)
{
return
-
Infinity
;
}
}
return
new
Date
(
value
);
}
return
value
;
};
BaseTypes
.
DATE
.
types
.
postgres
=
{
BaseTypes
.
DATE
.
types
.
postgres
=
{
oids
:
[
1184
],
oids
:
[
1184
],
array_oids
:
[
1185
]
array_oids
:
[
1185
]
...
...
lib/model.js
View file @
e01cc2f
...
@@ -920,6 +920,9 @@ class Model {
...
@@ -920,6 +920,9 @@ class Model {
});
});
});
});
this
.
_dataTypeChanges
=
{};
this
.
_dataTypeSanitizers
=
{};
this
.
_booleanAttributes
=
[];
this
.
_booleanAttributes
=
[];
this
.
_dateAttributes
=
[];
this
.
_dateAttributes
=
[];
this
.
_hstoreAttributes
=
[];
this
.
_hstoreAttributes
=
[];
...
@@ -952,6 +955,15 @@ class Model {
...
@@ -952,6 +955,15 @@ class Model {
this
.
fieldRawAttributesMap
[
definition
.
field
]
=
definition
;
this
.
fieldRawAttributesMap
[
definition
.
field
]
=
definition
;
if
(
definition
.
type
.
_sanitize
)
{
this
.
_dataTypeSanitizers
[
name
]
=
definition
.
type
.
_sanitize
;
}
if
(
definition
.
type
.
_isChanged
)
{
this
.
_dataTypeChanges
[
name
]
=
definition
.
type
.
_isChanged
;
}
if
(
definition
.
type
instanceof
DataTypes
.
BOOLEAN
)
{
if
(
definition
.
type
instanceof
DataTypes
.
BOOLEAN
)
{
this
.
_booleanAttributes
.
push
(
name
);
this
.
_booleanAttributes
.
push
(
name
);
}
else
if
(
definition
.
type
instanceof
DataTypes
.
DATE
||
definition
.
type
instanceof
DataTypes
.
DATEONLY
)
{
}
else
if
(
definition
.
type
instanceof
DataTypes
.
DATE
||
definition
.
type
instanceof
DataTypes
.
DATEONLY
)
{
...
@@ -1055,7 +1067,6 @@ class Model {
...
@@ -1055,7 +1067,6 @@ class Model {
Object
.
defineProperty
(
this
.
prototype
,
key
,
attributeManipulation
[
key
]);
Object
.
defineProperty
(
this
.
prototype
,
key
,
attributeManipulation
[
key
]);
}
}
this
.
prototype
.
rawAttributes
=
this
.
rawAttributes
;
this
.
prototype
.
rawAttributes
=
this
.
rawAttributes
;
this
.
prototype
.
attributes
=
Object
.
keys
(
this
.
prototype
.
rawAttributes
);
this
.
prototype
.
attributes
=
Object
.
keys
(
this
.
prototype
.
rawAttributes
);
this
.
prototype
.
_isAttribute
=
_
.
memoize
(
key
=>
this
.
prototype
.
attributes
.
indexOf
(
key
)
!==
-
1
);
this
.
prototype
.
_isAttribute
=
_
.
memoize
(
key
=>
this
.
prototype
.
attributes
.
indexOf
(
key
)
!==
-
1
);
...
@@ -3200,7 +3211,6 @@ class Model {
...
@@ -3200,7 +3211,6 @@ class Model {
this
.
_previousDataValues
=
_
.
clone
(
this
.
dataValues
);
this
.
_previousDataValues
=
_
.
clone
(
this
.
dataValues
);
}
else
{
}
else
{
// Loop and call set
// Loop and call set
if
(
options
.
attributes
)
{
if
(
options
.
attributes
)
{
let
keys
=
options
.
attributes
;
let
keys
=
options
.
attributes
;
if
(
this
.
constructor
.
_hasVirtualAttributes
)
{
if
(
this
.
constructor
.
_hasVirtualAttributes
)
{
...
@@ -3243,7 +3253,6 @@ class Model {
...
@@ -3243,7 +3253,6 @@ class Model {
}
}
}
else
{
}
else
{
// Check if we have included models, and if this key matches the include model names/aliases
// Check if we have included models, and if this key matches the include model names/aliases
if
(
this
.
_options
&&
this
.
_options
.
include
&&
this
.
_options
.
includeNames
.
indexOf
(
key
)
!==
-
1
)
{
if
(
this
.
_options
&&
this
.
_options
.
include
&&
this
.
_options
.
includeNames
.
indexOf
(
key
)
!==
-
1
)
{
// Pass it on to the include handler
// Pass it on to the include handler
this
.
_setInclude
(
key
,
value
,
options
);
this
.
_setInclude
(
key
,
value
,
options
);
...
@@ -3272,53 +3281,30 @@ class Model {
...
@@ -3272,53 +3281,30 @@ class Model {
if
(
!
this
.
isNewRecord
&&
this
.
constructor
.
_hasReadOnlyAttributes
&&
this
.
constructor
.
_isReadOnlyAttribute
(
key
))
{
if
(
!
this
.
isNewRecord
&&
this
.
constructor
.
_hasReadOnlyAttributes
&&
this
.
constructor
.
_isReadOnlyAttribute
(
key
))
{
return
this
;
return
this
;
}
}
// Convert date fields to real date objects
if
(
this
.
constructor
.
_hasDateAttributes
&&
this
.
constructor
.
_isDateAttribute
(
key
)
&&
!!
value
&&
!
(
value
instanceof
Utils
.
SequelizeMethod
))
{
// Dont parse DATEONLY to new Date, keep them as string
if
(
this
.
rawAttributes
[
key
].
type
instanceof
DataTypes
.
DATEONLY
)
{
if
(
originalValue
&&
originalValue
===
value
)
{
return
this
;
}
else
{
value
=
moment
(
value
).
format
(
'YYYY-MM-DD'
);
}
}
else
{
// go ahread and parse as Date if required
if
(
!
(
value
instanceof
Date
))
{
value
=
new
Date
(
value
);
}
if
(
originalValue
)
{
if
(
!
(
originalValue
instanceof
Date
))
{
originalValue
=
new
Date
(
originalValue
);
}
if
(
value
.
getTime
()
===
originalValue
.
getTime
())
{
return
this
;
}
}
}
}
}
// Convert boolean-ish values to booleans
if
(
this
.
constructor
.
_hasBooleanAttributes
&&
this
.
constructor
.
_isBooleanAttribute
(
key
)
&&
value
!==
null
&&
value
!==
undefined
&&
!
(
value
instanceof
Utils
.
SequelizeMethod
))
{
if
(
Buffer
.
isBuffer
(
value
)
&&
value
.
length
===
1
)
{
// Bit fields are returned as buffers
value
=
value
[
0
];
}
}
if
(
_
.
isString
(
value
))
{
// If there's a data type sanitizer
// Only take action on valid boolean strings.
if
(
!
(
value
instanceof
Utils
.
SequelizeMethod
)
&&
this
.
constructor
.
_dataTypeSanitizers
[
key
])
{
value
=
value
===
'true'
?
true
:
value
===
'false'
?
false
:
value
;
value
=
this
.
constructor
.
_dataTypeSanitizers
[
key
].
call
(
this
,
value
,
options
);
}
else
if
(
_
.
isNumber
(
value
))
{
// Only take action on valid boolean integers.
value
=
value
===
1
?
true
:
value
===
0
?
false
:
value
;
}
}
}
if
(
!
options
.
raw
&&
(
!
Utils
.
isPrimitive
(
value
)
&&
value
!==
null
||
value
!==
originalValue
))
{
// Set when the value has changed and not raw
if
(
!
options
.
raw
&&
(
// True when sequelize method
value
instanceof
Utils
.
SequelizeMethod
||
// Check for data type type comparators
!
(
value
instanceof
Utils
.
SequelizeMethod
)
&&
this
.
constructor
.
_dataTypeChanges
[
key
]
&&
this
.
constructor
.
_dataTypeChanges
[
key
].
call
(
this
,
value
,
originalValue
,
options
)
||
// Check default
!
this
.
constructor
.
_dataTypeChanges
[
key
]
&&
(
!
Utils
.
isPrimitive
(
value
)
&&
value
!==
null
||
value
!==
originalValue
)
)
)
{
this
.
_previousDataValues
[
key
]
=
originalValue
;
this
.
_previousDataValues
[
key
]
=
originalValue
;
this
.
changed
(
key
,
true
);
this
.
changed
(
key
,
true
);
}
}
// set data value
this
.
dataValues
[
key
]
=
value
;
this
.
dataValues
[
key
]
=
value
;
}
}
}
}
...
...
test/integration/data-types.test.js
View file @
e01cc2f
...
@@ -455,17 +455,64 @@ describe(Support.getTestDialectTeaser('DataTypes'), () => {
...
@@ -455,17 +455,64 @@ describe(Support.getTestDialectTeaser('DataTypes'), () => {
stamp
:
Sequelize
.
DATEONLY
stamp
:
Sequelize
.
DATEONLY
});
});
const
testDate
=
moment
().
format
(
'YYYY-MM-DD'
);
const
testDate
=
moment
().
format
(
'YYYY-MM-DD'
);
const
newDate
=
new
Date
();
return
Model
.
sync
({
force
:
true
})
return
Model
.
sync
({
force
:
true
})
.
then
(()
=>
Model
.
create
({
stamp
:
testDate
}))
.
then
(()
=>
Model
.
create
({
stamp
:
testDate
}))
.
then
(
record
=>
{
.
then
(
record
=>
{
expect
(
typeof
record
.
stamp
).
to
.
be
.
eql
(
'string'
);
expect
(
typeof
record
.
stamp
).
to
.
be
.
eql
(
'string'
);
expect
(
record
.
stamp
).
to
.
be
.
eql
(
testDate
);
expect
(
record
.
stamp
).
to
.
be
.
eql
(
testDate
);
return
Model
.
findById
(
record
.
id
);
return
Model
.
findById
(
record
.
id
);
}).
then
(
record
=>
{
}).
then
(
record
=>
{
expect
(
typeof
record
.
stamp
).
to
.
be
.
eql
(
'string'
);
expect
(
typeof
record
.
stamp
).
to
.
be
.
eql
(
'string'
);
expect
(
record
.
stamp
).
to
.
be
.
eql
(
testDate
);
expect
(
record
.
stamp
).
to
.
be
.
eql
(
testDate
);
return
record
.
update
({
stamp
:
testDate
});
}).
then
(
record
=>
{
return
record
.
reload
();
}).
then
(
record
=>
{
expect
(
typeof
record
.
stamp
).
to
.
be
.
eql
(
'string'
);
expect
(
record
.
stamp
).
to
.
be
.
eql
(
testDate
);
return
record
.
update
({
stamp
:
newDate
});
}).
then
(
record
=>
{
return
record
.
reload
();
}).
then
(
record
=>
{
expect
(
typeof
record
.
stamp
).
to
.
be
.
eql
(
'string'
);
expect
(
new
Date
(
record
.
stamp
)).
to
.
equalDate
(
newDate
);
});
});
});
});
it
(
'should be able to cast buffer as boolean'
,
function
()
{
const
ByteModel
=
this
.
sequelize
.
define
(
'Model'
,
{
byteToBool
:
this
.
sequelize
.
Sequelize
.
BLOB
},
{
timestamps
:
false
});
const
BoolModel
=
this
.
sequelize
.
define
(
'Model'
,
{
byteToBool
:
this
.
sequelize
.
Sequelize
.
BOOLEAN
},
{
timestamps
:
false
});
return
ByteModel
.
sync
({
force
:
true
}).
then
(()
=>
{
return
ByteModel
.
create
({
byteToBool
:
new
Buffer
([
true
])
});
}).
then
(
byte
=>
{
expect
(
byte
.
byteToBool
).
to
.
be
.
ok
;
return
BoolModel
.
findById
(
byte
.
id
);
}).
then
(
bool
=>
{
expect
(
bool
.
byteToBool
).
to
.
be
.
true
;
});
});
});
});
test/integration/dialects/postgres/data-types.test.js
0 → 100644
View file @
e01cc2f
'use strict'
;
const
chai
=
require
(
'chai'
);
const
expect
=
chai
.
expect
;
const
Support
=
require
(
__dirname
+
'/../../support'
);
const
dialect
=
Support
.
getTestDialect
();
const
DataTypes
=
require
(
__dirname
+
'/../../../../lib/data-types'
);
if
(
dialect
===
'postgres'
)
{
describe
(
'[POSTGRES Specific] Data Types'
,
()
=>
{
describe
(
'DATE/DATEONLY Validate and Stringify'
,
()
=>
{
const
now
=
new
Date
();
const
nowString
=
now
.
toISOString
();
it
(
'DATE should validate a Date as normal'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATE
().
validate
(
now
)).
to
.
equal
(
true
);
expect
(
DataTypes
[
dialect
].
DATE
().
validate
(
nowString
)).
to
.
equal
(
true
);
});
it
(
'DATE should validate Infinity/-Infinity as true'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATE
().
validate
(
Infinity
)).
to
.
equal
(
true
);
expect
(
DataTypes
[
dialect
].
DATE
().
validate
(
-
Infinity
)).
to
.
equal
(
true
);
});
it
(
'DATE should stringify Infinity/-Infinity to infinity/-infinity'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATE
().
stringify
(
Infinity
)).
to
.
equal
(
'Infinity'
);
expect
(
DataTypes
[
dialect
].
DATE
().
stringify
(
-
Infinity
)).
to
.
equal
(
'-Infinity'
);
});
it
(
'DATEONLY should stringify Infinity/-Infinity to infinity/-infinity'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATEONLY
().
stringify
(
Infinity
)).
to
.
equal
(
'Infinity'
);
expect
(
DataTypes
[
dialect
].
DATEONLY
().
stringify
(
-
Infinity
)).
to
.
equal
(
'-Infinity'
);
});
});
describe
(
'DATE/DATEONLY Sanitize'
,
()
=>
{
const
now
=
new
Date
();
const
nowString
=
now
.
toISOString
();
const
nowDateOnly
=
nowString
.
substr
(
0
,
10
);
it
(
'DATE should sanitize a Date as normal'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATE
().
_sanitize
(
now
)).
to
.
equalTime
(
now
);
expect
(
DataTypes
[
dialect
].
DATE
().
_sanitize
(
nowString
)).
to
.
equalTime
(
now
);
});
it
(
'DATE should sanitize Infinity/-Infinity as Infinity/-Infinity'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATE
().
_sanitize
(
Infinity
)).
to
.
equal
(
Infinity
);
expect
(
DataTypes
[
dialect
].
DATE
().
_sanitize
(
-
Infinity
)).
to
.
equal
(
-
Infinity
);
});
it
(
'DATE should sanitize "Infinity"/"-Infinity" as Infinity/-Infinity'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATE
().
_sanitize
(
'Infinity'
)).
to
.
equal
(
Infinity
);
expect
(
DataTypes
[
dialect
].
DATE
().
_sanitize
(
'-Infinity'
)).
to
.
equal
(
-
Infinity
);
});
it
(
'DATEONLY should sanitize a Date as normal'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATEONLY
().
_sanitize
(
now
)).
to
.
equal
(
nowDateOnly
);
expect
(
DataTypes
[
dialect
].
DATEONLY
().
_sanitize
(
nowString
)).
to
.
equal
(
nowDateOnly
);
});
it
(
'DATEONLY should sanitize Infinity/-Infinity as Infinity/-Infinity'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATEONLY
().
_sanitize
(
Infinity
)).
to
.
equal
(
Infinity
);
expect
(
DataTypes
[
dialect
].
DATEONLY
().
_sanitize
(
-
Infinity
)).
to
.
equal
(
-
Infinity
);
});
it
(
'DATEONLY should sanitize "Infinity"/"-Infinity" as Infinity/-Infinity'
,
()
=>
{
expect
(
DataTypes
[
dialect
].
DATEONLY
().
_sanitize
(
'Infinity'
)).
to
.
equal
(
Infinity
);
expect
(
DataTypes
[
dialect
].
DATEONLY
().
_sanitize
(
'-Infinity'
)).
to
.
equal
(
-
Infinity
);
});
});
describe
(
'DATE SQL'
,
()
=>
{
// create dummy user
it
(
'should be able to create and update records with Infinity/-Infinity'
,
function
()
{
this
.
sequelize
.
options
.
typeValidation
=
true
;
const
date
=
new
Date
();
const
User
=
this
.
sequelize
.
define
(
'User'
,
{
username
:
this
.
sequelize
.
Sequelize
.
STRING
,
beforeTime
:
{
type
:
this
.
sequelize
.
Sequelize
.
DATE
,
defaultValue
:
-
Infinity
},
sometime
:
{
type
:
this
.
sequelize
.
Sequelize
.
DATE
,
defaultValue
:
this
.
sequelize
.
fn
(
'NOW'
)
},
anotherTime
:
{
type
:
this
.
sequelize
.
Sequelize
.
DATE
},
afterTime
:
{
type
:
this
.
sequelize
.
Sequelize
.
DATE
,
defaultValue
:
Infinity
}
},
{
timestamps
:
true
});
return
User
.
sync
({
force
:
true
}).
then
(()
=>
{
return
User
.
create
({
username
:
'bob'
,
anotherTime
:
Infinity
},
{
validate
:
true
});
}).
then
(
user
=>
{
expect
(
user
.
username
).
to
.
equal
(
'bob'
);
expect
(
user
.
beforeTime
).
to
.
equal
(
-
Infinity
);
expect
(
user
.
sometime
).
to
.
be
.
withinTime
(
date
,
new
Date
());
expect
(
user
.
anotherTime
).
to
.
equal
(
Infinity
);
expect
(
user
.
afterTime
).
to
.
equal
(
Infinity
);
return
user
.
update
({
sometime
:
Infinity
},
{
returning
:
true
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
equal
(
Infinity
);
return
user
.
update
({
sometime
:
Infinity
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
equal
(
Infinity
);
return
user
.
update
({
sometime
:
this
.
sequelize
.
fn
(
'NOW'
)
},
{
returning
:
true
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
be
.
withinTime
(
date
,
new
Date
());
// find
return
User
.
findAll
();
}).
then
(
users
=>
{
expect
(
users
[
0
].
beforeTime
).
to
.
equal
(
-
Infinity
);
expect
(
users
[
0
].
sometime
).
to
.
not
.
equal
(
Infinity
);
expect
(
users
[
0
].
afterTime
).
to
.
equal
(
Infinity
);
return
users
[
0
].
update
({
sometime
:
date
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
equalTime
(
date
);
return
user
.
update
({
sometime
:
date
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
equalTime
(
date
);
});
});
});
describe
(
'DATEONLY SQL'
,
()
=>
{
// create dummy user
it
(
'should be able to create and update records with Infinity/-Infinity'
,
function
()
{
this
.
sequelize
.
options
.
typeValidation
=
true
;
const
date
=
new
Date
();
const
User
=
this
.
sequelize
.
define
(
'User'
,
{
username
:
this
.
sequelize
.
Sequelize
.
STRING
,
beforeTime
:
{
type
:
this
.
sequelize
.
Sequelize
.
DATEONLY
,
defaultValue
:
-
Infinity
},
sometime
:
{
type
:
this
.
sequelize
.
Sequelize
.
DATEONLY
,
defaultValue
:
this
.
sequelize
.
fn
(
'NOW'
)
},
anotherTime
:
{
type
:
this
.
sequelize
.
Sequelize
.
DATEONLY
},
afterTime
:
{
type
:
this
.
sequelize
.
Sequelize
.
DATEONLY
,
defaultValue
:
Infinity
}
},
{
timestamps
:
true
});
return
User
.
sync
({
force
:
true
}).
then
(()
=>
{
return
User
.
create
({
username
:
'bob'
,
anotherTime
:
Infinity
},
{
validate
:
true
});
}).
then
(
user
=>
{
expect
(
user
.
username
).
to
.
equal
(
'bob'
);
expect
(
user
.
beforeTime
).
to
.
equal
(
-
Infinity
);
expect
(
new
Date
(
user
.
sometime
)).
to
.
be
.
withinDate
(
date
,
new
Date
());
expect
(
user
.
anotherTime
).
to
.
equal
(
Infinity
);
expect
(
user
.
afterTime
).
to
.
equal
(
Infinity
);
return
user
.
update
({
sometime
:
Infinity
},
{
returning
:
true
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
equal
(
Infinity
);
return
user
.
update
({
sometime
:
Infinity
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
equal
(
Infinity
);
return
user
.
update
({
sometime
:
this
.
sequelize
.
fn
(
'NOW'
)
},
{
returning
:
true
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
not
.
equal
(
Infinity
);
expect
(
new
Date
(
user
.
sometime
)).
to
.
be
.
withinDate
(
date
,
new
Date
());
// find
return
User
.
findAll
();
}).
then
(
users
=>
{
expect
(
users
[
0
].
beforeTime
).
to
.
equal
(
-
Infinity
);
expect
(
users
[
0
].
sometime
).
to
.
not
.
equal
(
Infinity
);
expect
(
users
[
0
].
afterTime
).
to
.
equal
(
Infinity
);
return
users
[
0
].
update
({
sometime
:
'1969-07-20'
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
equal
(
'1969-07-20'
);
return
user
.
update
({
sometime
:
'1969-07-20'
});
}).
then
(
user
=>
{
expect
(
user
.
sometime
).
to
.
equal
(
'1969-07-20'
);
});
});
});
});
}
test/integration/model/geography.test.js
View file @
e01cc2f
...
@@ -175,6 +175,52 @@ describe(Support.getTestDialectTeaser('Model'), () => {
...
@@ -175,6 +175,52 @@ describe(Support.getTestDialectTeaser('Model'), () => {
});
});
});
});
if
(
current
.
dialect
.
name
===
'postgres'
)
{
describe
(
'GEOGRAPHY(POLYGON, SRID)'
,
()
=>
{
beforeEach
(
function
()
{
this
.
User
=
this
.
sequelize
.
define
(
'User'
,
{
username
:
DataTypes
.
STRING
,
geography
:
DataTypes
.
GEOGRAPHY
(
'POLYGON'
,
4326
)
});
return
this
.
User
.
sync
({
force
:
true
});
});
it
(
'should create a geography object'
,
function
()
{
const
User
=
this
.
User
;
const
point
=
{
type
:
'Polygon'
,
coordinates
:
[
[
[
100.0
,
0.0
],
[
101.0
,
0.0
],
[
101.0
,
1.0
],
[
100.0
,
1.0
],
[
100.0
,
0.0
]
]
]};
return
User
.
create
({
username
:
'username'
,
geography
:
point
}).
then
(
newUser
=>
{
expect
(
newUser
).
not
.
to
.
be
.
null
;
expect
(
newUser
.
geography
).
to
.
be
.
deep
.
eql
(
point
);
});
});
it
(
'should update a geography object'
,
function
()
{
const
User
=
this
.
User
;
const
polygon1
=
{
type
:
'Polygon'
,
coordinates
:
[
[
[
100.0
,
0.0
],
[
101.0
,
0.0
],
[
101.0
,
1.0
],
[
100.0
,
1.0
],
[
100.0
,
0.0
]
]
]},
polygon2
=
{
type
:
'Polygon'
,
coordinates
:
[
[
[
100.0
,
0.0
],
[
102.0
,
0.0
],
[
102.0
,
1.0
],
[
100.0
,
1.0
],
[
100.0
,
0.0
]
]
]};
const
props
=
{
username
:
'username'
,
geography
:
polygon1
};
return
User
.
create
(
props
).
then
(()
=>
{
return
User
.
update
({
geography
:
polygon2
},
{
where
:
{
username
:
props
.
username
}});
}).
then
(()
=>
{
return
User
.
findOne
({
where
:
{
username
:
props
.
username
}});
}).
then
(
user
=>
{
expect
(
user
.
geography
).
to
.
be
.
deep
.
eql
(
polygon2
);
});
});
});
}
describe
(
'sql injection attacks'
,
()
=>
{
describe
(
'sql injection attacks'
,
()
=>
{
beforeEach
(
function
()
{
beforeEach
(
function
()
{
this
.
Model
=
this
.
sequelize
.
define
(
'Model'
,
{
this
.
Model
=
this
.
sequelize
.
define
(
'Model'
,
{
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment