diff --git a/CHANGELOG.md b/CHANGELOG.md index 27c072b..d98f085 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +* Add Date Time Range type + v1.2.0 * Return null for null dates rather than the unix epoch. diff --git a/Type.sbvr b/Type.sbvr index 27ac05e..d133427 100644 --- a/Type.sbvr +++ b/Type.sbvr @@ -86,4 +86,21 @@ Fact type: Color has Green Component Fact type: Color has Blue Component Necessity: Each Color has exactly one Blue Component Fact type: Color has Alpha Component - Necessity: Each Color has exactly one Alpha Component \ No newline at end of file + Necessity: Each Color has exactly one Alpha Component + +Term: Start + Concept Type: Date Time +Term: End + Concept Type: Date Time +Term: Bounds + Concept Type: Short Text +Term: Date Time Range + Concept Type: Short Text +Fact type: Date Time Range has Start + Necessity: Each Date Time Range has exactly one Start +Fact Type: Date Time Range has End + Necessity: Each Date Time Range has at most one End +Fact Type: Date Time Range has Bounds + Necessity: Each Date Time Range has exactly one Bounds +Fact Type: Date Time Range is inclusive or exclusive of Start +Fact Type: Date Time Range is inclusive or exclusive of End \ No newline at end of file diff --git a/src/TypeUtils.coffee b/src/TypeUtils.coffee index a8148d3..bb3066a 100644 --- a/src/TypeUtils.coffee +++ b/src/TypeUtils.coffee @@ -37,4 +37,17 @@ do -> callback('is not a valid date: ' + value) else callback(null, processedValue) + + dataTypeGen: (dbType, engine, dataType, necessity, index = '', defaultValue) -> + necessity = if necessity then ' NOT NULL' else ' NULL' + defaultValue = if defaultValue then " DEFAULT #{defaultValue}" + if index != '' + index = ' ' + index + if dbType? + if _.isFunction(dbType) + return dbType(necessity, index) + defaultValue ?= '' + return dbType + defaultValue + necessity + index + else + throw new Error("Unknown data type '#{dataType}' for engine: #{engine}") } diff --git a/src/types/Boolean.coffee b/src/types/Boolean.coffee index e0b3ad8..0348534 100644 --- a/src/types/Boolean.coffee +++ b/src/types/Boolean.coffee @@ -19,4 +19,14 @@ do -> callback("is not a boolean: #{JSON.stringify(originalValue)} (#{typeof originalValue})") else callback(null, value) + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Color.coffee b/src/types/Color.coffee index 6852b1e..0b4f4d4 100644 --- a/src/types/Color.coffee +++ b/src/types/Color.coffee @@ -53,4 +53,14 @@ callback('has an unknown component: ' + component) return callback(null, processedValue) + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/ConceptType.coffee b/src/types/ConceptType.coffee index 6fe02b6..fae5970 100644 --- a/src/types/ConceptType.coffee +++ b/src/types/ConceptType.coffee @@ -11,4 +11,14 @@ Real: TypeUtils.nativeFactTypeTemplates.comparison validate: TypeUtils.validate.integer + +dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Date Time Range.coffee b/src/types/Date Time Range.coffee new file mode 100644 index 0000000..a1a6791 --- /dev/null +++ b/src/types/Date Time Range.coffee @@ -0,0 +1,66 @@ +{ + types: + postgres: 'TSTZRANGE' + mysql: 'VARCHAR(255)' + websql: 'VARCHAR(255)' + odata: + name: 'Self.DateTimeRange' + complexType: ''' + + \ + \ + \ + ''' + + nativeProperties: + has: + Start: (from) -> ['RangeStart', from] + End: (from) -> ['RangeEnd', from] + Bounds: (from) -> ['RangeBounds', from] + + fetchProcessing: (data, callback) -> + if data? + [start, end] = data.slice(1, -1).split(',') + res = + Start: start + End: end.trim() + Bounds: data[0] + data[data.length - 1] + callback(null, res) + else + callback(null, data) + + validate: (value, required, callback) -> + if !_.isObject(value) + callback('is not a date time range object: ' + value) + else + # Check with hasOwnProperty since null values are allowed + if value.hasOwnProperty('Start') and value.hasOwnProperty('End') and value.hasOwnProperty('Bounds') + processedValue = '' + start = undefined + end = undefined + bounds = undefined + for own component, componentValue of value + switch component.toLowerCase() + when 'start' + start = componentValue + when 'end' + end = componentValue + when 'bounds' + bounds = componentValue + else + callback('has an unknown component: ' + component) + processedValue = bounds[0] + start + ', ' + end + bounds[1] + callback(null, processedValue) + else + callback('is missing components: ' + value) + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue +} \ No newline at end of file diff --git a/src/types/Date Time.coffee b/src/types/Date Time.coffee index 8c19caa..cdc4add 100644 --- a/src/types/Date Time.coffee +++ b/src/types/Date Time.coffee @@ -12,4 +12,14 @@ callback(null, data) validate: TypeUtils.validate.date + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue != 'CURRENT_TIMESTAMP' + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Date.coffee b/src/types/Date.coffee index 644c3e1..7d9d808 100644 --- a/src/types/Date.coffee +++ b/src/types/Date.coffee @@ -12,4 +12,14 @@ callback(null, data) validate: TypeUtils.validate.date + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/File.coffee b/src/types/File.coffee index 97d03c7..51917bc 100644 --- a/src/types/File.coffee +++ b/src/types/File.coffee @@ -17,4 +17,14 @@ callback(null, value) else callback("could not be converted to binary: #{typeof value}") + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/ForeignKey.coffee b/src/types/ForeignKey.coffee index 6fe02b6..940c24e 100644 --- a/src/types/ForeignKey.coffee +++ b/src/types/ForeignKey.coffee @@ -11,4 +11,14 @@ Real: TypeUtils.nativeFactTypeTemplates.comparison validate: TypeUtils.validate.integer + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Hashed.coffee b/src/types/Hashed.coffee index 5ea7bbb..745da0e 100644 --- a/src/types/Hashed.coffee +++ b/src/types/Hashed.coffee @@ -22,4 +22,14 @@ do -> .asCallback(callback) compare: _.bind(bcrypt.compareAsync, bcrypt) + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Integer.coffee b/src/types/Integer.coffee index 6fe02b6..940c24e 100644 --- a/src/types/Integer.coffee +++ b/src/types/Integer.coffee @@ -11,4 +11,14 @@ Real: TypeUtils.nativeFactTypeTemplates.comparison validate: TypeUtils.validate.integer + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Interval.coffee b/src/types/Interval.coffee index 6437c1b..df65b52 100644 --- a/src/types/Interval.coffee +++ b/src/types/Interval.coffee @@ -7,4 +7,14 @@ name: 'Edm.Int64' validate: TypeUtils.validate.integer + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/JSON.coffee b/src/types/JSON.coffee index 2bacd1c..b3e9f2a 100644 --- a/src/types/JSON.coffee +++ b/src/types/JSON.coffee @@ -18,4 +18,14 @@ catch e console.error(e) callback('cannot be turned into JSON: ' + value) + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Real.coffee b/src/types/Real.coffee index 72a84b0..264fcf0 100644 --- a/src/types/Real.coffee +++ b/src/types/Real.coffee @@ -16,4 +16,14 @@ callback('is not a number: ' + value) else callback(null, processedValue) + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Serial.coffee b/src/types/Serial.coffee index 3e32004..e076b0d 100644 --- a/src/types/Serial.coffee +++ b/src/types/Serial.coffee @@ -9,4 +9,14 @@ name: 'Edm.Int64' validate: TypeUtils.validate.integer + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Short Text.coffee b/src/types/Short Text.coffee index 16e11b5..edf7d43 100644 --- a/src/types/Short Text.coffee +++ b/src/types/Short Text.coffee @@ -7,4 +7,14 @@ name: 'Edm.String' validate: TypeUtils.validate.text(255) + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Text.coffee b/src/types/Text.coffee index 8eec34f..60e5933 100644 --- a/src/types/Text.coffee +++ b/src/types/Text.coffee @@ -14,4 +14,14 @@ Text: TypeUtils.nativeFactTypeTemplates.equality validate: TypeUtils.validate.text() + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/src/types/Time.coffee b/src/types/Time.coffee index a2d83f6..c5314d6 100644 --- a/src/types/Time.coffee +++ b/src/types/Time.coffee @@ -18,4 +18,14 @@ callback(err) return callback(null, value.toLocaleTimeString()) + + dataTypeGen: (engine, dataType, necessity, index = '', defaultValue) -> + if defaultValue + @validate defaultValue, true, (err, value) -> + if !err + defaultValue = value + else + defaultValue = null + dbType = @types?[engine] + TypeUtils.dataTypeGen dbType, engine, dataType, necessity, index, defaultValue } diff --git a/test/Date Time Range.coffee b/test/Date Time Range.coffee new file mode 100644 index 0000000..630d817 --- /dev/null +++ b/test/Date Time Range.coffee @@ -0,0 +1,22 @@ +helpers = require './helpers' + +helpers.describe 'Date Time Range', (test) -> + start = new Date() + end = 'null' + bounds = '[)' + describe 'fetchProcessing', -> + test.fetch(bounds[0] + start + ', ' + end + bounds[1], { + Start: start.toString() + End: end + Bounds: bounds + }) + + describe 'validate', -> + start = new Date() + end = null + bounds = '[)' + test.validate({ + Start: start + End: end + Bounds: bounds + }, true, bounds[0] + start + ', ' + end + bounds[1]) \ No newline at end of file