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 916473b5
authored
Mar 02, 2013
by
Sascha Depold
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed renameColumn and changeColumn for sqlite (and partially pg)
1 parent
8183a0eb
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
221 additions
and
63 deletions
lib/dialects/postgres/query-generator.js
lib/dialects/postgres/query.js
lib/dialects/sqlite/query-generator.js
lib/dialects/sqlite/query-interface.js
lib/dialects/sqlite/query.js
lib/query-interface.js
lib/utils.js
spec/migrator.spec.js
spec/postgres/dao.spec.js
lib/dialects/postgres/query-generator.js
View file @
916473b
...
...
@@ -179,6 +179,7 @@ module.exports = (function() {
tableName
:
addQuotes
(
tableName
),
query
:
addQuotes
(
attributeName
)
+
' SET NOT NULL'
})
definition
=
definition
.
replace
(
'NOT NULL'
,
''
).
trim
()
}
else
{
attrSql
+=
Utils
.
_
.
template
(
query
)({
...
...
@@ -187,6 +188,20 @@ module.exports = (function() {
})
}
if
(
definition
.
indexOf
(
'DEFAULT'
)
>
0
)
{
attrSql
+=
Utils
.
_
.
template
(
query
)({
tableName
:
addQuotes
(
tableName
),
query
:
addQuotes
(
attributeName
)
+
' SET DEFAULT'
+
definition
.
match
(
/DEFAULT
([^
;
]
+
)
/
)[
1
]
})
definition
=
definition
.
replace
(
/
(
DEFAULT
[^
;
]
+
)
/
,
''
).
trim
()
}
else
{
attrSql
+=
Utils
.
_
.
template
(
query
)({
tableName
:
addQuotes
(
tableName
),
query
:
addQuotes
(
attributeName
)
+
' DROP DEFAULT'
})
}
if
(
definition
.
match
(
/^ENUM
\(
/
))
{
query
=
pgEnum
(
tableName
,
attributeName
,
definition
)
+
query
definition
=
definition
.
replace
(
/^ENUM
\(
.+
\)
/
,
Utils
.
escape
(
"enum_"
+
tableName
+
"_"
+
attributeName
))
...
...
lib/dialects/postgres/query.js
View file @
916473b
...
...
@@ -90,6 +90,14 @@ module.exports = (function() {
result
[
_result
.
Field
].
defaultValue
=
null
}
}
if
(
typeof
result
[
_result
.
Field
].
defaultValue
===
'string'
)
{
result
[
_result
.
Field
].
defaultValue
=
result
[
_result
.
Field
].
defaultValue
.
replace
(
/'/g
,
""
)
if
(
result
[
_result
.
Field
].
defaultValue
.
indexOf
(
'::'
)
>
-
1
)
{
result
[
_result
.
Field
].
defaultValue
=
result
[
_result
.
Field
].
defaultValue
.
split
(
'::'
)[
0
]
}
}
})
this
.
emit
(
'success'
,
result
)
...
...
lib/dialects/sqlite/query-generator.js
View file @
916473b
var
Utils
=
require
(
"../../utils"
)
,
DataTypes
=
require
(
"../../data-types"
)
var
MySqlQueryGenerator
=
Utils
.
_
.
extend
(
Utils
.
_
.
clone
(
require
(
"../query-generator"
)),
Utils
.
_
.
clone
(
require
(
"../mysql/query-generator"
))
...
...
@@ -252,12 +253,36 @@ module.exports = (function() {
"DROP TABLE <%= tableName %>;"
,
QueryGenerator
.
createTableQuery
(
tableName
,
attributes
),
"INSERT INTO <%= tableName %> SELECT <%= attributeNames %> FROM <%= tableName %>_backup;"
,
"DROP TABLE <%= tableName %>_backup;"
,
"DROP TABLE <%= tableName %>_backup;"
].
join
(
""
)
return
Utils
.
_
.
template
(
query
,
{
tableName
:
tableName
,
attributeNames
:
Utils
.
_
.
keys
(
attributes
).
join
(
', '
)
})
},
renameColumnQuery
:
function
(
tableName
,
attrNameBefore
,
attrNameAfter
,
attributes
)
{
attributes
=
QueryGenerator
.
attributesToSQL
(
attributes
)
var
backupTableName
=
tableName
+
"_backup"
var
query
=
[
QueryGenerator
.
createTableQuery
(
backupTableName
,
attributes
).
replace
(
'CREATE TABLE'
,
'CREATE TEMPORARY TABLE'
),
"INSERT INTO <%= tableName %>_backup SELECT <%= attributeNamesImport %> FROM <%= tableName %>;"
,
"DROP TABLE <%= tableName %>;"
,
QueryGenerator
.
createTableQuery
(
tableName
,
attributes
),
"INSERT INTO <%= tableName %> SELECT <%= attributeNamesExport %> FROM <%= tableName %>_backup;"
,
"DROP TABLE <%= tableName %>_backup;"
].
join
(
""
)
return
Utils
.
_
.
template
(
query
,
{
tableName
:
tableName
,
attributeNames
:
Utils
.
_
.
keys
(
attributes
)
attributeNamesImport
:
Utils
.
_
.
keys
(
attributes
).
map
(
function
(
attr
)
{
return
(
attrNameAfter
===
attr
)
?
attrNameBefore
+
' AS '
+
attr
:
attr
}).
join
(
', '
),
attributeNamesExport
:
Utils
.
_
.
keys
(
attributes
).
map
(
function
(
attr
)
{
return
attr
}).
join
(
', '
)
})
},
...
...
lib/dialects/sqlite/query-interface.js
0 → 100644
View file @
916473b
Utils
=
require
(
"../../utils"
)
/**
Returns an object that treats SQLite's inabilities to do certain queries.
@class QueryInterface
@static
*/
var
QueryInterface
=
module
.
exports
=
{
/**
A wrapper that fixes SQLite's inability to remove columns from existing tables.
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but without the obsolete column.
@method removeColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {String} attributeName The name of the attribute that we want to remove.
@param {CustomEventEmitter} emitter The EventEmitter from outside.
@param {Function} queryAndEmit The function from outside that triggers some events to get triggered.
@since 1.6.0
*/
removeColumn
:
function
(
tableName
,
attributeName
,
emitter
,
queryAndEmit
)
{
this
.
describeTable
(
tableName
).
complete
(
function
(
err
,
fields
)
{
if
(
err
)
{
emitter
.
emit
(
'error'
,
err
)
}
else
{
delete
fields
[
attributeName
]
var
sql
=
this
.
QueryGenerator
.
removeColumnQuery
(
tableName
,
fields
)
,
subQueries
=
sql
.
split
(
';'
).
filter
(
function
(
q
)
{
return
q
!==
''
})
QueryInterface
.
execMultiQuery
.
call
(
this
,
subQueries
,
'removeColumn'
,
emitter
,
queryAndEmit
)
}
}.
bind
(
this
))
},
/**
A wrapper that fixes SQLite's inability to change columns from existing tables.
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but with a modified version of the respective column.
@method changeColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {Object} attributes An object with the attribute's name as key and it's options as value object.
@param {CustomEventEmitter} emitter The EventEmitter from outside.
@param {Function} queryAndEmit The function from outside that triggers some events to get triggered.
@since 1.6.0
*/
changeColumn
:
function
(
tableName
,
attributes
,
emitter
,
queryAndEmit
)
{
var
attributeName
=
Utils
.
_
.
keys
(
attributes
)[
0
]
this
.
describeTable
(
tableName
).
complete
(
function
(
err
,
fields
)
{
if
(
err
)
{
emitter
.
emit
(
'error'
,
err
)
}
else
{
fields
[
attributeName
]
=
attributes
[
attributeName
]
var
sql
=
this
.
QueryGenerator
.
removeColumnQuery
(
tableName
,
fields
)
,
subQueries
=
sql
.
split
(
';'
).
filter
(
function
(
q
)
{
return
q
!==
''
})
QueryInterface
.
execMultiQuery
.
call
(
this
,
subQueries
,
'changeColumn'
,
emitter
,
queryAndEmit
)
}
}.
bind
(
this
))
},
/**
A wrapper that fixes SQLite's inability to rename columns from existing tables.
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but with a renamed version of the respective column.
@method renameColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {String} attrNameBefore The name of the attribute before it was renamed.
@param {String} attrNameAfter The name of the attribute after it was renamed.
@param {CustomEventEmitter} emitter The EventEmitter from outside.
@param {Function} queryAndEmit The function from outside that triggers some events to get triggered.
@since 1.6.0
*/
renameColumn
:
function
(
tableName
,
attrNameBefore
,
attrNameAfter
,
emitter
,
queryAndEmit
)
{
this
.
describeTable
(
tableName
).
complete
(
function
(
err
,
fields
)
{
if
(
err
)
{
emitter
.
emit
(
'error'
,
err
)
}
else
{
fields
[
attrNameAfter
]
=
Utils
.
_
.
clone
(
fields
[
attrNameBefore
])
delete
fields
[
attrNameBefore
]
var
sql
=
this
.
QueryGenerator
.
renameColumnQuery
(
tableName
,
attrNameBefore
,
attrNameAfter
,
fields
)
,
subQueries
=
sql
.
split
(
';'
).
filter
(
function
(
q
)
{
return
q
!==
''
})
QueryInterface
.
execMultiQuery
.
call
(
this
,
subQueries
,
'renameColumn'
,
emitter
,
queryAndEmit
)
}
}.
bind
(
this
))
},
execMultiQuery
:
function
(
queries
,
methodName
,
emitter
,
queryAndEmit
)
{
var
chainer
=
new
Utils
.
QueryChainer
()
queries
.
splice
(
0
,
queries
.
length
-
1
).
forEach
(
function
(
query
)
{
chainer
.
add
(
this
.
sequelize
,
'query'
,
[
query
+
";"
,
null
,
{
raw
:
true
}])
}.
bind
(
this
))
chainer
.
runSerially
()
.
complete
(
function
(
err
)
{
if
(
err
)
{
emitter
.
emit
(
methodName
,
err
)
emitter
.
emit
(
'error'
,
err
)
}
else
{
queryAndEmit
.
call
(
this
,
queries
.
splice
(
queries
.
length
-
1
)[
0
],
methodName
,
{},
emitter
)
}
}.
bind
(
this
))
}
}
lib/dialects/sqlite/query.js
View file @
916473b
...
...
@@ -128,6 +128,10 @@ module.exports = (function() {
if
(
result
[
_result
.
name
].
defaultValue
===
undefined
)
{
result
[
_result
.
name
].
defaultValue
=
null
}
if
(
typeof
result
[
_result
.
name
].
defaultValue
===
'string'
)
{
result
[
_result
.
name
].
defaultValue
=
result
[
_result
.
name
].
defaultValue
.
replace
(
/'/g
,
""
)
}
})
}
...
...
lib/query-interface.js
View file @
916473b
var
Utils
=
require
(
'./utils'
)
,
DataTypes
=
require
(
'./data-types'
)
var
Utils
=
require
(
'./utils'
)
,
DataTypes
=
require
(
'./data-types'
)
,
SQLiteQueryInterface
=
require
(
'./dialects/sqlite/query-interface'
)
module
.
exports
=
(
function
()
{
var
QueryInterface
=
function
(
sequelize
)
{
...
...
@@ -14,7 +15,7 @@ module.exports = (function() {
Utils
.
_
.
each
(
attributes
,
function
(
dataTypeOrOptions
,
attributeName
)
{
if
(
Utils
.
_
.
values
(
DataTypes
).
indexOf
(
dataTypeOrOptions
)
>
-
1
)
{
attributeHashes
[
attributeName
]
=
{
type
:
dataTypeOrOptions
}
attributeHashes
[
attributeName
]
=
{
type
:
dataTypeOrOptions
,
allowNull
:
true
}
}
else
{
attributeHashes
[
attributeName
]
=
dataTypeOrOptions
}
...
...
@@ -117,32 +118,7 @@ module.exports = (function() {
if
(
this
.
sequelize
.
options
.
dialect
===
'sqlite'
)
{
// sqlite needs some special treatment as it cannot drop a column
return
new
Utils
.
CustomEventEmitter
(
function
(
emitter
)
{
this
.
describeTable
(
tableName
).
complete
(
function
(
err
,
fields
)
{
if
(
err
)
{
emitter
.
emit
(
'error'
,
err
)
}
else
{
delete
fields
[
attributeName
]
var
sql
=
this
.
QueryGenerator
.
removeColumnQuery
(
tableName
,
fields
)
,
chainer
=
new
Utils
.
QueryChainer
()
,
subQueries
=
sql
.
split
(
';'
).
filter
(
function
(
q
)
{
return
q
!==
''
})
subQueries
.
splice
(
0
,
subQueries
.
length
-
1
).
forEach
(
function
(
subQuery
)
{
chainer
.
add
(
this
.
sequelize
,
'query'
,
[
subQuery
+
";"
,
null
,
{
raw
:
true
}])
}.
bind
(
this
))
chainer
.
runSerially
()
.
complete
(
function
(
err
)
{
if
(
err
)
{
emitter
.
emit
(
'removeColumn'
,
err
)
emitter
.
emit
(
'error'
,
err
)
}
else
{
queryAndEmit
.
call
(
this
,
subQueries
.
splice
(
subQueries
.
length
-
1
)[
0
],
'removeColumn'
)
}
}.
bind
(
this
))
}
}.
bind
(
this
))
SQLiteQueryInterface
.
removeColumn
.
call
(
this
,
tableName
,
attributeName
,
emitter
,
queryAndEmit
)
}.
bind
(
this
)).
run
()
}
else
{
var
sql
=
this
.
QueryGenerator
.
removeColumnQuery
(
tableName
,
attributeName
)
...
...
@@ -154,50 +130,54 @@ module.exports = (function() {
var
attributes
=
{}
if
(
Utils
.
_
.
values
(
DataTypes
).
indexOf
(
dataTypeOrOptions
)
>
-
1
)
{
attributes
[
attributeName
]
=
{
type
:
dataTypeOrOptions
,
allowNull
:
fals
e
}
attributes
[
attributeName
]
=
{
type
:
dataTypeOrOptions
,
allowNull
:
tru
e
}
}
else
{
attributes
[
attributeName
]
=
dataTypeOrOptions
}
var
options
=
this
.
QueryGenerator
.
attributesToSQL
(
attributes
)
,
sql
=
this
.
QueryGenerator
.
changeColumnQuery
(
tableName
,
options
)
if
(
this
.
sequelize
.
options
.
dialect
===
'sqlite'
)
{
// sqlite needs some special treatment as it cannot change a column
return
new
Utils
.
CustomEventEmitter
(
function
(
emitter
)
{
SQLiteQueryInterface
.
changeColumn
.
call
(
this
,
tableName
,
attributes
,
emitter
,
queryAndEmit
)
}.
bind
(
this
)).
run
()
}
else
{
var
options
=
this
.
QueryGenerator
.
attributesToSQL
(
attributes
)
,
sql
=
this
.
QueryGenerator
.
changeColumnQuery
(
tableName
,
options
)
return
queryAndEmit
.
call
(
this
,
sql
,
'changeColumn'
)
return
queryAndEmit
.
call
(
this
,
sql
,
'changeColumn'
)
}
}
QueryInterface
.
prototype
.
renameColumn
=
function
(
tableName
,
attrNameBefore
,
attrNameAfter
)
{
var
self
=
this
return
new
Utils
.
CustomEventEmitter
(
function
(
emitter
)
{
self
.
describeTable
(
tableName
).
success
(
function
(
data
)
{
this
.
describeTable
(
tableName
).
success
(
function
(
data
)
{
data
=
data
[
attrNameBefore
]
||
{}
var
options
=
{}
options
[
attrNameAfter
]
=
{
attribute
:
attrNameAfter
,
type
:
data
.
type
,
allowNull
:
data
.
allowNull
,
attribute
:
attrNameAfter
,
type
:
data
.
type
,
allowNull
:
data
.
allowNull
,
defaultValue
:
data
.
defaultValue
}
var
sql
=
self
.
QueryGenerator
.
renameColumnQuery
(
tableName
,
attrNameBefore
,
self
.
QueryGenerator
.
attributesToSQL
(
options
)
)
self
.
sequelize
.
query
(
sql
,
null
,
{}).
success
(
function
()
{
self
.
emit
(
'renameColumn'
,
null
)
emitter
.
emit
(
'success'
,
null
)
}).
error
(
function
(
err
)
{
self
.
emit
(
'renameColumn'
,
err
)
emitter
.
emit
(
'error'
,
err
)
})
}).
error
(
function
(
err
)
{
self
.
emit
(
'renameColumn'
,
err
)
if
(
this
.
sequelize
.
options
.
dialect
===
'sqlite'
)
{
// sqlite needs some special treatment as it cannot rename a column
SQLiteQueryInterface
.
renameColumn
.
call
(
this
,
tableName
,
attrNameBefore
,
attrNameAfter
,
emitter
,
queryAndEmit
)
}
else
{
var
sql
=
this
.
QueryGenerator
.
renameColumnQuery
(
tableName
,
attrNameBefore
,
this
.
QueryGenerator
.
attributesToSQL
(
options
)
)
queryAndEmit
.
call
(
this
,
sql
,
'renameColumn'
,
{},
emitter
)
}
}.
bind
(
this
))
.
error
(
function
(
err
)
{
this
.
emit
(
'renameColumn'
,
err
)
emitter
.
emit
(
'error'
,
err
)
})
}).
run
()
}
.
bind
(
this
)
)
}
.
bind
(
this
)
).
run
()
}
QueryInterface
.
prototype
.
addIndex
=
function
(
tableName
,
attributes
,
options
)
{
...
...
lib/utils.js
View file @
916473b
var
util
=
require
(
"util"
)
,
DataTypes
=
require
(
"./data-types"
)
,
SqlString
=
require
(
"./
SqlS
tring"
)
,
SqlString
=
require
(
"./
sql-s
tring"
)
var
Utils
=
module
.
exports
=
{
_
:
(
function
()
{
...
...
spec/migrator.spec.js
View file @
916473b
...
...
@@ -170,7 +170,7 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
it
(
"executes migration #20111205064000 and renames a table"
,
function
(
done
)
{
this
.
sequelize
.
getQueryInterface
().
showAllTables
().
success
(
function
(
tableNames
)
{
tableNames
=
tableNames
.
filter
(
function
(
e
){
return
e
!=
'SequelizeMeta'
})
expect
(
tableNames
).
to
Equal
([
'Person'
]
)
expect
(
tableNames
).
to
Contain
(
'Person'
)
this
.
init
({
from
:
20111205064000
,
to
:
20111205064000
},
function
(
migrator
)
{
migrator
.
migrate
().
success
(
function
()
{
...
...
@@ -234,13 +234,17 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
})
describe
(
'changeColumn'
,
function
()
{
(
dialect
===
'mysql'
?
it
:
itEventually
)
(
'changes the signature column from user to default "signature" + notNull'
,
function
(
done
)
{
it
(
'changes the signature column from user to default "signature" + notNull'
,
function
(
done
)
{
this
.
init
({
to
:
20111206063000
},
function
(
migrator
)
{
migrator
.
migrate
().
success
(
function
()
{
this
.
sequelize
.
getQueryInterface
().
describeTable
(
'User'
).
success
(
function
(
data
)
{
var
signature
=
data
.
signature
expect
(
signature
.
type
).
toEqual
(
'VARCHAR(255)'
)
if
(
dialect
===
'postgres'
)
{
expect
(
signature
.
type
).
toEqual
(
'CHARACTER VARYING'
)
}
else
{
expect
(
signature
.
type
).
toEqual
(
'VARCHAR(255)'
)
}
expect
(
signature
.
allowNull
).
toEqual
(
false
)
expect
(
signature
.
defaultValue
).
toEqual
(
'Signature'
)
...
...
@@ -253,7 +257,7 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
})
describe
(
'renameColumn'
,
function
()
{
(
dialect
===
'mysql'
?
it
:
itEventually
)
(
"renames the signature column from user to sig"
,
function
(
done
)
{
it
(
"renames the signature column from user to sig"
,
function
(
done
)
{
this
.
init
({
to
:
20111206163300
},
function
(
migrator
)
{
migrator
.
migrate
().
success
(
function
(){
this
.
sequelize
.
getQueryInterface
().
describeTable
(
'User'
).
success
(
function
(
data
)
{
...
...
spec/postgres/dao.spec.js
View file @
916473b
...
...
@@ -10,7 +10,7 @@ if (dialect.match(/^postgres/)) {
describe
(
'[POSTGRES] DAO'
,
function
()
{
before
(
function
(
done
)
{
var
self
=
this
console
.
log
(
"to init"
);
Helpers
.
initTests
({
dialect
:
dialect
,
beforeComplete
:
function
(
sequelize
,
DataTypes
)
{
...
...
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