Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
yotta
/
pictogram
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
60
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
b1c42a56
authored
Jul 14, 2016
by
Arturo Montejo Ráez
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
updated files in sails-mysql to support milliseconds in timestamps
parent
9a587e6e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
770 additions
and
3 deletions
.gitignore
sails/src/node_modules/sails-mysql/lib/sql.js
sails/src/node_modules/sails-mysql/lib/utils.js
.gitignore
View file @
b1c42a56
...
...
@@ -22,9 +22,6 @@ sails/src/assets/app/modules
sails/src/assets/app/css
sails/src/assets/app/js
sails/src/assets/scripts/config.js
# Other #
#########
sails/src/config/ssl/**/*.key
sails/src/config/ssl/**/*.crt
sails/src/config/ssl/**/*.csr
...
...
@@ -36,6 +33,12 @@ sails/npm-debug.log
sails/playbook.retry
sails/upload.zip
# NOT to be ignored #
# This files override sails-mysql files to support milliseconds timestamps #
############################################################################
!sails/src/node_modules/sails-mysql/lib/sql.js
!sails/src/node_modules/sails-mysql/lib/utils.js
# Android #
###########
.idea
...
...
sails/src/node_modules/sails-mysql/lib/sql.js
0 → 100644
View file @
b1c42a56
/**
* Module Dependencies
*/
var
mysql
=
require
(
'mysql'
);
var
_
=
require
(
'lodash'
);
var
utils
=
require
(
'./utils'
);
var
sql
=
module
.
exports
=
{
// Convert mysql format to standard javascript object
normalizeSchema
:
function
(
schema
)
{
return
_
.
reduce
(
schema
,
function
(
memo
,
field
)
{
// Marshal mysql DESCRIBE to waterline collection semantics
var
attrName
=
field
.
Field
;
var
type
=
field
.
Type
;
// Remove (n) column-size indicators
type
=
type
.
replace
(
/
\([
0-9
]
+
\)
$/
,
''
);
memo
[
attrName
]
=
{
type
:
type
,
defaultsTo
:
field
.
Default
,
autoIncrement
:
field
.
Extra
===
'auto_increment'
};
if
(
field
.
primaryKey
)
{
memo
[
attrName
].
primaryKey
=
field
.
primaryKey
;
}
if
(
field
.
unique
)
{
memo
[
attrName
].
unique
=
field
.
unique
;
}
if
(
field
.
indexed
)
{
memo
[
attrName
].
indexed
=
field
.
indexed
;
}
return
memo
;
},
{});
},
// @returns ALTER query for adding a column
addColumn
:
function
(
collectionName
,
attrName
,
attrDef
)
{
// Escape table name and attribute name
var
tableName
=
mysql
.
escapeId
(
collectionName
);
// sails.log.verbose("ADDING ",attrName, "with",attrDef);
// Build column definition
var
columnDefinition
=
sql
.
_schema
(
collectionName
,
attrDef
,
attrName
);
return
'ALTER TABLE '
+
tableName
+
' ADD '
+
columnDefinition
;
},
// @returns ALTER query for dropping a column
removeColumn
:
function
(
collectionName
,
attrName
)
{
// Escape table name and attribute name
var
tableName
=
mysql
.
escapeId
(
collectionName
);
attrName
=
mysql
.
escapeId
(
attrName
);
return
'ALTER TABLE '
+
tableName
+
' DROP COLUMN '
+
attrName
;
},
countQuery
:
function
(
collectionName
,
options
,
tableDefs
){
var
query
=
'SELECT count(*) as count from `'
+
collectionName
+
'`'
;
return
query
+=
sql
.
serializeOptions
(
collectionName
,
options
,
tableDefs
);
},
// Create a schema csv for a DDL query
schema
:
function
(
collectionName
,
attributes
)
{
return
sql
.
build
(
collectionName
,
attributes
,
sql
.
_schema
);
},
_schema
:
function
(
collectionName
,
attribute
,
attrName
)
{
attrName
=
mysql
.
escapeId
(
attrName
);
var
type
=
sqlTypeCast
(
attribute
);
// Process PK field
if
(
attribute
.
primaryKey
)
{
var
columnDefinition
=
attrName
+
' '
+
type
;
// If type is an integer, set auto increment
if
(
type
===
'TINYINT'
||
type
===
'SMALLINT'
||
type
===
'INT'
||
type
===
'BIGINT'
)
{
return
columnDefinition
+
' UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY'
;
}
// Just set NOT NULL on other types
return
columnDefinition
+
' NOT NULL PRIMARY KEY'
;
}
// Process NOT NULL field.
// if notNull is true, set NOT NULL constraint
var
nullPart
=
''
;
if
(
attribute
.
notNull
)
{
nullPart
=
' NOT NULL '
;
}
// Process UNIQUE field
if
(
attribute
.
unique
)
{
return
attrName
+
' '
+
type
+
nullPart
+
' UNIQUE KEY'
;
}
// Process INDEX field (NON-UNIQUE KEY)
if
(
attribute
.
index
)
{
return
attrName
+
' '
+
type
+
nullPart
+
', INDEX('
+
attrName
+
')'
;
}
return
attrName
+
' '
+
type
+
' '
+
nullPart
;
},
// Create an attribute csv for a DQL query
attributes
:
function
(
collectionName
,
attributes
)
{
return
sql
.
build
(
collectionName
,
attributes
,
sql
.
prepareAttribute
);
},
// Create a value csv for a DQL query
// key => optional, overrides the keys in the dictionary
values
:
function
(
collectionName
,
values
,
key
)
{
return
sql
.
build
(
collectionName
,
values
,
sql
.
prepareValue
,
', '
,
key
);
},
prepareCriterion
:
function
(
collectionName
,
value
,
key
,
parentKey
)
{
// Special sub-attr case
if
(
validSubAttrCriteria
(
value
))
{
return
sql
.
where
(
collectionName
,
value
,
null
,
key
);
}
// Build escaped attr and value strings using either the key,
// or if one exists, the parent key
var
attrStr
,
valueStr
;
// Special comparator case
if
(
parentKey
)
{
attrStr
=
sql
.
prepareAttribute
(
collectionName
,
value
,
parentKey
);
valueStr
=
sql
.
prepareValue
(
collectionName
,
value
,
parentKey
);
// Why don't we strip you out of those bothersome apostrophes?
var
nakedButClean
=
String
(
valueStr
).
replace
(
new
RegExp
(
'^\'+|\'+$'
,
'g'
),
''
);
if
(
key
===
'<'
||
key
===
'lessThan'
)
{
return
attrStr
+
'<'
+
valueStr
;
}
else
if
(
key
===
'<='
||
key
===
'lessThanOrEqual'
)
{
return
attrStr
+
'<='
+
valueStr
;
}
else
if
(
key
===
'>'
||
key
===
'greaterThan'
)
{
return
attrStr
+
'>'
+
valueStr
;
}
else
if
(
key
===
'>='
||
key
===
'greaterThanOrEqual'
)
{
return
attrStr
+
'>='
+
valueStr
;
}
else
if
(
key
===
'!'
||
key
===
'not'
)
{
if
(
value
===
null
)
{
return
attrStr
+
' IS NOT NULL'
;
}
else
if
(
_
.
isArray
(
value
))
{
return
attrStr
+
' NOT IN('
+
valueStr
+
')'
;
}
else
{
return
attrStr
+
'<>'
+
valueStr
;
}
}
else
if
(
key
===
'like'
)
{
return
attrStr
+
' LIKE \''
+
nakedButClean
+
'\''
;
}
else
if
(
key
===
'contains'
)
{
return
attrStr
+
' LIKE \'%'
+
nakedButClean
+
'%\''
;
}
else
if
(
key
===
'startsWith'
)
{
return
attrStr
+
' LIKE \''
+
nakedButClean
+
'%\''
;
}
else
if
(
key
===
'endsWith'
)
{
return
attrStr
+
' LIKE \'%'
+
nakedButClean
+
'\''
;
}
else
{
throw
new
Error
(
'Unknown comparator: '
+
key
);
}
}
else
{
attrStr
=
sql
.
prepareAttribute
(
collectionName
,
value
,
key
);
valueStr
=
sql
.
prepareValue
(
collectionName
,
value
,
key
);
// Special IS NULL case
if
(
_
.
isNull
(
value
))
{
return
attrStr
+
' IS NULL'
;
}
else
{
return
attrStr
+
'='
+
valueStr
;
}
}
},
prepareValue
:
function
(
collectionName
,
value
,
attrName
)
{
// Cast dates to SQL
if
(
_
.
isDate
(
value
))
{
value
=
toSqlDate
(
value
);
}
// Cast functions to strings
if
(
_
.
isFunction
(
value
))
{
value
=
value
.
toString
();
}
// Escape (also wraps in quotes)
return
mysql
.
escape
(
value
);
},
prepareAttribute
:
function
(
collectionName
,
value
,
attrName
)
{
return
mysql
.
escapeId
(
collectionName
)
+
'.'
+
mysql
.
escapeId
(
attrName
);
},
// // Starting point for predicate evaluation
// // parentKey => if set, look for comparators and apply them to the parent key
where
:
function
(
collectionName
,
where
,
key
,
parentKey
)
{
return
sql
.
build
(
collectionName
,
where
,
sql
.
predicate
,
' AND '
,
undefined
,
parentKey
);
},
// Recursively parse a predicate calculus and build a SQL query
predicate
:
function
(
collectionName
,
criterion
,
key
,
parentKey
)
{
var
queryPart
=
''
;
if
(
parentKey
)
{
return
sql
.
prepareCriterion
(
collectionName
,
criterion
,
key
,
parentKey
);
}
// OR
if
(
key
.
toLowerCase
()
===
'or'
)
{
queryPart
=
sql
.
build
(
collectionName
,
criterion
,
sql
.
where
,
' OR '
);
return
' ( '
+
queryPart
+
' ) '
;
}
// AND
else
if
(
key
.
toLowerCase
()
===
'and'
)
{
queryPart
=
sql
.
build
(
collectionName
,
criterion
,
sql
.
where
,
' AND '
);
return
' ( '
+
queryPart
+
' ) '
;
}
// IN
else
if
(
_
.
isArray
(
criterion
))
{
queryPart
=
sql
.
prepareAttribute
(
collectionName
,
null
,
key
)
+
' IN ('
+
sql
.
values
(
collectionName
,
criterion
,
key
)
+
')'
;
return
queryPart
;
}
// LIKE
else
if
(
key
.
toLowerCase
()
===
'like'
)
{
return
sql
.
build
(
collectionName
,
criterion
,
function
(
collectionName
,
value
,
attrName
)
{
var
attrStr
=
sql
.
prepareAttribute
(
collectionName
,
value
,
attrName
);
// TODO: Handle regexp criterias
if
(
_
.
isRegExp
(
value
))
{
throw
new
Error
(
'RegExp LIKE criterias not supported by the MySQLAdapter yet. Please contribute @ http://github.com/balderdashy/sails-mysql'
);
}
var
valueStr
=
sql
.
prepareValue
(
collectionName
,
value
,
attrName
);
// Handle escaped percent (%) signs [encoded as %%%]
valueStr
=
valueStr
.
replace
(
/%%%/g
,
'\\%'
);
return
attrStr
+
' LIKE '
+
valueStr
;
},
' AND '
);
}
// NOT
else
if
(
key
.
toLowerCase
()
===
'not'
)
{
throw
new
Error
(
'NOT not supported yet!'
);
}
// Basic criteria item
else
{
return
sql
.
prepareCriterion
(
collectionName
,
criterion
,
key
);
}
},
serializeOptions
:
function
(
collectionName
,
options
,
tableDefs
)
{
// Join clause
// allow the key to be named with join or joins
var
joins
=
options
.
join
||
options
.
joins
||
[];
if
(
joins
.
length
>
0
)
{
return
this
.
buildJoinQuery
(
collectionName
,
joins
,
options
,
tableDefs
);
}
return
this
.
buildSingleQuery
(
collectionName
,
options
,
tableDefs
);
},
/**
* Build Up a Select Statement Without Joins
*/
buildSingleQuery
:
function
(
collectionName
,
options
,
tableDefs
)
{
var
queryPart
=
''
;
if
(
options
.
where
)
{
queryPart
+=
'WHERE '
+
sql
.
where
(
collectionName
,
options
.
where
)
+
' '
;
}
if
(
options
.
groupBy
)
{
queryPart
+=
'GROUP BY '
;
// Normalize to array
if
(
!
_
.
isArray
(
options
.
groupBy
))
{
options
.
groupBy
=
[
options
.
groupBy
];
}
_
.
each
(
options
.
groupBy
,
function
(
key
)
{
queryPart
+=
key
+
', '
;
});
// Remove trailing comma
queryPart
=
queryPart
.
slice
(
0
,
-
2
)
+
' '
;
}
if
(
options
.
sort
)
{
queryPart
+=
'ORDER BY '
;
// Sort through each sort attribute criteria
_
.
each
(
options
.
sort
,
function
(
direction
,
attrName
)
{
queryPart
+=
sql
.
prepareAttribute
(
collectionName
,
null
,
attrName
)
+
' '
;
// Basic MongoDB-style numeric sort direction
if
(
direction
===
1
)
{
queryPart
+=
'ASC, '
;
}
else
{
queryPart
+=
'DESC, '
;
}
});
// Remove trailing comma
if
(
queryPart
.
slice
(
-
2
)
===
', '
)
{
queryPart
=
queryPart
.
slice
(
0
,
-
2
)
+
' '
;
}
}
if
(
_
.
has
(
options
,
'limit'
)
&&
(
options
.
limit
!==
null
&&
options
.
limit
!==
undefined
))
{
queryPart
+=
'LIMIT '
+
options
.
limit
+
' '
;
}
if
(
_
.
has
(
options
,
'skip'
)
&&
(
options
.
skip
!==
null
&&
options
.
skip
!==
undefined
))
{
// Some MySQL hackery here. For details, see:
// http://stackoverflow.com/questions/255517/mysql-offset-infinite-rows
if
(
!
options
.
limit
)
{
queryPart
+=
'LIMIT 18446744073709551610 '
;
}
queryPart
+=
'OFFSET '
+
options
.
skip
+
' '
;
}
return
queryPart
;
},
// Put together the CSV aggregation
// separator => optional, defaults to ', '
// keyOverride => optional, overrides the keys in the dictionary
// (used for generating value lists in IN queries)
// parentKey => key of the parent to this object
build
:
function
(
collectionName
,
collection
,
fn
,
separator
,
keyOverride
,
parentKey
)
{
separator
=
separator
||
', '
;
var
$sql
=
''
;
_
.
each
(
collection
,
function
(
value
,
key
)
{
$sql
+=
fn
(
collectionName
,
value
,
keyOverride
||
key
,
parentKey
);
// (always append separator)
$sql
+=
separator
;
});
// (then remove final one)
return
String
(
$sql
).
replace
(
new
RegExp
(
separator
+
'+$'
),
''
);
}
};
// Cast waterline types into SQL data types
function
sqlTypeCast
(
attr
)
{
var
type
;
var
size
;
var
expandedType
;
if
(
_
.
isObject
(
attr
)
&&
_
.
has
(
attr
,
'type'
))
{
type
=
attr
.
type
;
}
else
{
type
=
attr
;
}
type
=
type
&&
type
.
toLowerCase
();
switch
(
type
)
{
case
'string'
:
{
size
=
255
;
// By default.
// If attr.size is positive integer, use it as size of varchar.
if
(
!
Number
.
isNaN
(
attr
.
size
)
&&
(
parseInt
(
attr
.
size
)
===
parseFloat
(
attr
.
size
))
&&
(
parseInt
(
attr
.
size
)
>
0
))
{
size
=
attr
.
size
;
}
expandedType
=
'VARCHAR('
+
size
+
')'
;
break
;
}
case
'text'
:
case
'array'
:
case
'json'
:
expandedType
=
'LONGTEXT'
;
break
;
case
'mediumtext'
:
expandedType
=
'mediumtext'
;
break
;
case
'longtext'
:
expandedType
=
'longtext'
;
break
;
case
'boolean'
:
expandedType
=
'BOOL'
;
break
;
case
'int'
:
case
'integer'
:
{
size
=
32
;
// By default
if
(
!
Number
.
isNaN
(
attr
.
size
)
&&
(
parseInt
(
attr
.
size
)
===
parseFloat
(
attr
.
size
))
&&
(
parseInt
(
size
)
>
0
))
{
size
=
parseInt
(
attr
.
size
);
}
// MEDIUMINT gets internally promoted to INT so there is no real benefit
// using it.
switch
(
size
)
{
case
8
:
expandedType
=
'TINYINT'
;
break
;
case
16
:
expandedType
=
'SMALLINT'
;
break
;
case
32
:
expandedType
=
'INT'
;
break
;
case
64
:
expandedType
=
'BIGINT'
;
break
;
default
:
expandedType
=
'INT'
;
break
;
}
break
;
}
case
'float'
:
case
'double'
:
expandedType
=
'FLOAT'
;
break
;
case
'decimal'
:
expandedType
=
'DECIMAL'
;
break
;
case
'date'
:
expandedType
=
'DATE'
;
break
;
case
'datetime'
:
expandedType
=
'DATETIME(3)'
;
break
;
case
'time'
:
expandedType
=
'TIME'
;
break
;
case
'binary'
:
expandedType
=
'BLOB'
;
break
;
default
:
console
.
error
(
'Unregistered type given: '
+
type
);
expandedType
=
'LONGTEXT'
;
break
;
}
return
expandedType
;
}
function
wrapInQuotes
(
val
)
{
return
'"'
+
val
+
'"'
;
}
function
toSqlDate
(
date
)
{
date
=
date
.
getFullYear
()
+
'-'
+
(
'00'
+
(
date
.
getMonth
()
+
1
)).
slice
(
-
2
)
+
'-'
+
(
'00'
+
date
.
getDate
()).
slice
(
-
2
)
+
' '
+
(
'00'
+
date
.
getHours
()).
slice
(
-
2
)
+
':'
+
(
'00'
+
date
.
getMinutes
()).
slice
(
-
2
)
+
':'
+
(
'00'
+
date
.
getSeconds
()).
slice
(
-
2
)
+
'.'
+
(
'00'
+
date
.
getMilliseconds
()).
slice
(
-
3
);
return
date
;
}
// Return whether this criteria is valid as an object inside of an attribute
function
validSubAttrCriteria
(
c
)
{
return
_
.
isObject
(
c
)
&&
(
!
_
.
isUndefined
(
c
.
not
)
||
!
_
.
isUndefined
(
c
.
greaterThan
)
||
!
_
.
isUndefined
(
c
.
lessThan
)
||
!
_
.
isUndefined
(
c
.
greaterThanOrEqual
)
||
!
_
.
isUndefined
(
c
.
lessThanOrEqual
)
||
!
_
.
isUndefined
(
c
[
'<'
])
||
!
_
.
isUndefined
(
c
[
'<='
])
||
!
_
.
isUndefined
(
c
[
'!'
])
||
!
_
.
isUndefined
(
c
[
'>'
])
||
!
_
.
isUndefined
(
c
[
'>='
])
||
!
_
.
isUndefined
(
c
.
startsWith
)
||
!
_
.
isUndefined
(
c
.
endsWith
)
||
!
_
.
isUndefined
(
c
.
contains
)
||
!
_
.
isUndefined
(
c
.
like
));
}
sails/src/node_modules/sails-mysql/lib/utils.js
0 → 100644
View file @
b1c42a56
/**
* Utility Functions
*/
// Dependencies
var
mysql
=
require
(
'mysql'
);
var
_
=
require
(
'lodash'
);
var
url
=
require
(
'url'
);
// Module Exports
var
utils
=
module
.
exports
=
{};
/**
* Parse URL string from config
*
* Parse URL string into connection config parameters
*/
utils
.
parseUrl
=
function
(
config
)
{
if
(
!
_
.
isString
(
config
.
url
))
{
return
config
;
}
var
obj
=
url
.
parse
(
config
.
url
);
config
.
host
=
obj
.
hostname
||
config
.
host
;
config
.
port
=
obj
.
port
||
config
.
port
;
if
(
_
.
isString
(
obj
.
pathname
))
{
config
.
database
=
obj
.
pathname
.
split
(
'/'
)[
1
]
||
config
.
database
;
}
if
(
_
.
isString
(
obj
.
auth
))
{
config
.
user
=
obj
.
auth
.
split
(
':'
)[
0
]
||
config
.
user
;
config
.
password
=
obj
.
auth
.
split
(
':'
)[
1
]
||
config
.
password
;
}
return
config
;
};
/**
* Prepare values
*
* Transform a JS date to SQL date and functions
* to strings.
*/
utils
.
prepareValue
=
function
(
value
)
{
if
(
_
.
isUndefined
(
value
)
||
value
===
null
)
{
return
value
;
}
// Cast functions to strings
if
(
_
.
isFunction
(
value
))
{
value
=
value
.
toString
();
}
// Store Arrays and Objects as strings
if
(
_
.
isArray
(
value
)
||
value
.
constructor
&&
value
.
constructor
.
name
===
'Object'
)
{
try
{
value
=
JSON
.
stringify
(
value
);
}
catch
(
e
)
{
// just keep the value and let the db handle an error
value
=
value
;
}
}
// Cast dates to SQL
if
(
_
.
isDate
(
value
))
{
value
=
utils
.
toSqlDate
(
value
);
}
return
mysql
.
escape
(
value
);
};
/**
* Builds a Select statement determining if Aggeregate options are needed.
*/
utils
.
buildSelectStatement
=
function
(
criteria
,
table
,
schemaDefs
)
{
var
query
=
''
;
if
(
criteria
.
groupBy
||
criteria
.
sum
||
criteria
.
average
||
criteria
.
min
||
criteria
.
max
)
{
query
=
'SELECT '
;
// Append groupBy columns to select statement
if
(
criteria
.
groupBy
)
{
if
(
_
.
isArray
(
criteria
.
groupBy
))
{
_
.
each
(
criteria
.
groupBy
,
function
(
opt
){
query
+=
opt
+
', '
;
});
}
else
{
query
+=
criteria
.
groupBy
+
', '
;
}
}
// Handle SUM
if
(
criteria
.
sum
)
{
if
(
_
.
isArray
(
criteria
.
sum
))
{
_
.
each
(
criteria
.
sum
,
function
(
opt
){
query
+=
'SUM('
+
opt
+
') AS '
+
opt
+
', '
;
});
}
else
{
query
+=
'SUM('
+
criteria
.
sum
+
') AS '
+
criteria
.
sum
+
', '
;
}
}
// Handle AVG (casting to float to fix percision with trailing zeros)
if
(
criteria
.
average
)
{
if
(
_
.
isArray
(
criteria
.
average
))
{
_
.
each
(
criteria
.
average
,
function
(
opt
){
query
+=
'AVG('
+
opt
+
') AS '
+
opt
+
', '
;
});
}
else
{
query
+=
'AVG('
+
criteria
.
average
+
') AS '
+
criteria
.
average
+
', '
;
}
}
// Handle MAX
if
(
criteria
.
max
)
{
if
(
_
.
isArray
(
criteria
.
max
))
{
_
.
each
(
criteria
.
max
,
function
(
opt
){
query
+=
'MAX('
+
opt
+
') AS '
+
opt
+
', '
;
});
}
else
{
query
+=
'MAX('
+
criteria
.
max
+
') AS '
+
criteria
.
max
+
', '
;
}
}
// Handle MIN
if
(
criteria
.
min
)
{
if
(
_
.
isArray
(
criteria
.
min
))
{
_
.
each
(
criteria
.
min
,
function
(
opt
){
query
+=
'MIN('
+
opt
+
') AS '
+
opt
+
', '
;
});
}
else
{
query
+=
'MIN('
+
criteria
.
min
+
') AS '
+
criteria
.
min
+
', '
;
}
}
// trim trailing comma
query
=
query
.
slice
(
0
,
-
2
)
+
' '
;
// Add FROM clause
return
query
+=
'FROM `'
+
table
+
'` '
;
}
/**
* If no aggregate options lets just build a normal query
*/
// Add all keys to the select statement for this table
query
+=
'SELECT '
;
var
selectKeys
=
[],
joinSelectKeys
=
[];
if
(
!
schemaDefs
[
table
]
)
{
throw
new
Error
(
'Schema definition missing for table: `'
+
table
+
'`'
);
}
_
.
each
(
schemaDefs
[
table
],
function
(
schemaDef
,
key
)
{
selectKeys
.
push
({
table
:
table
,
key
:
key
});
});
// Check for joins
if
(
criteria
.
joins
||
criteria
.
join
)
{
var
joins
=
criteria
.
joins
||
criteria
.
join
;
_
.
each
(
joins
,
function
(
join
)
{
if
(
!
join
.
select
)
{
return
;
}
_
.
each
(
_
.
keys
(
schemaDefs
[
join
.
child
.
toLowerCase
()]),
function
(
key
)
{
var
_join
=
_
.
cloneDeep
(
join
);
_join
.
key
=
key
;
joinSelectKeys
.
push
(
_join
);
});
// Remove the foreign key for this join from the selectKeys array
selectKeys
=
selectKeys
.
filter
(
function
(
select
)
{
var
keep
=
true
;
if
(
select
.
key
===
join
.
parentKey
&&
join
.
removeParentKey
)
{
keep
=
false
;
}
return
keep
;
});
});
}
// Add all the columns to be selected that are not joins
_
.
each
(
selectKeys
,
function
(
select
)
{
query
+=
'`'
+
select
.
table
+
'`.`'
+
select
.
key
+
'`, '
;
});
// Add all the columns from the joined tables
_
.
each
(
joinSelectKeys
,
function
(
select
)
{
// Create an alias by prepending the child table with the alias of the join
var
alias
=
select
.
alias
.
toLowerCase
()
+
'_'
+
select
.
child
.
toLowerCase
();
// If this is a belongs_to relationship, keep the foreign key name from the AS part
// of the query. This will result in a selected column like: "user"."id" AS "user_id__id"
if
(
select
.
model
)
{
return
query
+=
mysql
.
escapeId
(
alias
)
+
'.'
+
mysql
.
escapeId
(
select
.
key
)
+
' AS '
+
mysql
.
escapeId
(
select
.
parentKey
+
'__'
+
select
.
key
)
+
', '
;
}
// If a junctionTable is used, the child value should be used in the AS part of the
// select query.
if
(
select
.
junctionTable
)
{
return
query
+=
mysql
.
escapeId
(
alias
)
+
'.'
+
mysql
.
escapeId
(
select
.
key
)
+
' AS '
+
mysql
.
escapeId
(
select
.
alias
+
'__'
+
select
.
key
)
+
', '
;
}
// Else if a hasMany attribute is being selected, use the alias plus the child
return
query
+=
mysql
.
escapeId
(
alias
)
+
'.'
+
mysql
.
escapeId
(
select
.
key
)
+
' AS '
+
mysql
.
escapeId
(
select
.
alias
+
'__'
+
select
.
key
)
+
', '
;
});
// Remove the last comma
query
=
query
.
slice
(
0
,
-
2
)
+
' FROM `'
+
table
+
'` '
;
return
query
;
};
utils
.
toSqlDate
=
function
toSqlDate
(
date
)
{
date
=
date
.
getFullYear
()
+
'-'
+
(
'00'
+
(
date
.
getMonth
()
+
1
)).
slice
(
-
2
)
+
'-'
+
(
'00'
+
date
.
getDate
()).
slice
(
-
2
)
+
' '
+
(
'00'
+
date
.
getHours
()).
slice
(
-
2
)
+
':'
+
(
'00'
+
date
.
getMinutes
()).
slice
(
-
2
)
+
':'
+
(
'00'
+
date
.
getSeconds
()).
slice
(
-
2
)
+
'.'
+
(
'00'
+
date
.
getMilliseconds
()).
slice
(
-
2
);
return
date
;
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
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 comment