rob*_*bro 2 javascript html5 persistence
我目前正在尝试使用PersistenceJS的迁移插件对现有数据库进行更改.我可以添加/编辑/删除数据库中的项目 - 但是......
如何更改现有(!)列的类型,例如从"text"更改为"integer"?
These changes should retain currently existing data.
可悲的是,文档有点稀缺,也许你可以帮忙吗?
这是当前的工作设置:
persistence.store.websql.config(persistence, 'tododatabase', 'todos are fun', 5*1024*1024);
var Todo = persistence.define('Todo', {
task: 'TEXT',
priority: 'INT',
done: 'BOOL'
});
persistence.schemaSync();
function addTodo( item ){
var todo = new Todo();
todo.task = item.task;
todo.priority = item.priority;
todo.done = item.done;
persistence.add(todo);
persistence.flush();
};
function deleteTodo( item, callback ){
// item.id was created automatically by calling "new Todo()"
Todo.all().filter('id','=', item.id ).destroyAll( function(){
persistence.flush( callback );
});
};
Run Code Online (Sandbox Code Playgroud)
有点工作的迁移代码:
persistence.defineMigration(1, {
up: function() {
this.createTable('Todo', function(t){
t.text('task');
t.integer('priority');
t.boolean('done');
});
},
down: function() {
this.dropTable('Todo');
}
});
persistence.defineMigration(2, {
up: function() {
this.addColumn('Todo', 'due', 'DATE');
},
down: function() {
this.removeColumn('Todo', 'due');
}
});
function migrate( callback ){
console.log('migrating...');
persistence.migrations.init( function(){
console.log('migration init');
// this should migrate up to the latest version, in our case: 2
persistence.migrate( function(){
console.log('migration complete!');
} );
});
}
Run Code Online (Sandbox Code Playgroud)
persistence.store.websql.config(persistence, 'newdatabase', 'testing migration', 5*1024*1024);,而不是调用schemaSync(),只调用migrate()将成功记录"迁移完成!" - 但它在一个新的,完全空的数据库"newdatabase"中这样做,当然不会保留任何现有数据.还有为利用创建的数据库persistence.store.websql.config(...),persistence.define('Todo',...)和persistence.schemaSync().
我现在想要保留该数据库中已存在的所有数据,但希望如此
priority从"整数"更改为"文本"due向所有现有Todos 添加类型为"date" 的列如果你能把我推向正确的方向,我将非常感激!
谢谢!
我终于搞定了.我的初始要求存在许多问题,我想指出以供将来参考.看一下第一个迁移定义:
persistence.defineMigration(1, {
up: function() {
this.createTable('Todo', function(t){
...
Run Code Online (Sandbox Code Playgroud)
毫不奇怪,它createTable会做到这一点:它将执行SQL语句'CREATE TABLE Todo ...',如果有一个Todo已经有名称的表,它将默默地失败并停止迁移.这就是为什么它适用于新数据库,而不是现有数据库.请记住:我已经拥有一个带有"Todo"表的实时数据库,需要更新.如果你刚刚开始新鲜(即你没有使用过schemaSync),那就行createTable得很好.由于迁移插件不提供createTableIfNotExists方法,我需要使用executeSql如下:
persistence.defineMigration(1, {
up: function() {
this.executeSql('CREATE TABLE IF NOT EXISTS Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority INT, done BOOL)');
...
Run Code Online (Sandbox Code Playgroud)
既然从模式版本0到1的迁移成功,那么迁移到版本2也是成功的.
迁移到版本3时,priority需要将列的类型更改int为text.这通常是使用ALTER COLUMNSQL命令完成的,Web SQL/SQLite不支持.请参阅SQLite的省略功能.
使用SQLite更改列需要一个4步骤的解决方法:
persistence.defineMigration(3, {
up: function() {
// rename current table
this.executeSql('ALTER TABLE Todo RENAME TO OldTodo');
// create new table with required columns and column types
this.executeSql('CREATE TABLE Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority TEXT, done BOOL)');
// copy contents from old table to new table
this.executeSql('INSERT INTO Todo(id, task, priority, done) SELECT id, task, priority, done FROM OldTodo');
// delete old table
this.executeSql('DROP TABLE OldTodo');
},
...
Run Code Online (Sandbox Code Playgroud)
当然,在更改列类型后,还应更改"Todo"的实体定义:
var Todo = persistence.define('Todo', {
task: 'TEXT',
priority: 'TEXT', // was 'INT'
due: 'DATE',
done: 'BOOL'
});
Run Code Online (Sandbox Code Playgroud)
persistence.store.websql.config(persistence, 'tododatabase', 'todos are fun', 5*1024*1024);
// persistence.debug = true;
//v0 + v1
// var Todo = persistence.define('Todo', {
// task: 'TEXT',
// priority: 'INT',
// done: 'BOOL'
// });
//v2
// var Todo = persistence.define('Todo', {
// task: 'TEXT',
// priority: 'INT',
// due: 'DATE',
// done: 'BOOL'
// });
//v3
var Todo = persistence.define('Todo', {
task: 'TEXT',
priority: 'TEXT',
due: 'DATE',
done: 'BOOL'
});
persistence.defineMigration(1, {
up: function() {
this.executeSql('CREATE TABLE IF NOT EXISTS Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority INT, done BOOL)');
},
down: function() {
this.dropTable('Todo');
}
});
persistence.defineMigration(2, {
up: function() {
this.addColumn('Todo', 'due', 'DATE');
},
down: function() {
this.removeColumn('Todo', 'due');
}
});
persistence.defineMigration(3, {
up: function() {
// rename current table
this.executeSql('ALTER TABLE Todo RENAME TO OldTodo');
// create new table with required columns
this.executeSql('CREATE TABLE Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority TEXT, due DATE, done BOOL)');
// copy contents from old table to new table
this.executeSql('INSERT INTO Todo(id, task, priority, due, done) SELECT id, task, priority, due, done FROM OldTodo');
// delete current table
this.executeSql('DROP TABLE OldTodo');
},
down: function() {
this.executeSql('ALTER TABLE Todo RENAME TO OldTodo');
this.executeSql('CREATE TABLE Todo (id VARCHAR(32) PRIMARY KEY, task TEXT, priority INT, due DATE, done BOOL)');
this.executeSql('INSERT INTO Todo(id, task, priority, due, done) SELECT id, task, priority, due, done FROM OldTodo');
this.executeSql('DROP TABLE OldTodo');
}
});
function migrate( callback ){
console.log('migrating...');
persistence.migrations.init( function(){
console.log('migration init');
persistence.migrate( function(){
console.debug('migration complete!');
callback();
} );
});
};
migrate( onMigrationComplete );
function onMigrationComplete(){
// database is ready. do amazing things...
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1871 次 |
| 最近记录: |