我正在使用PhoneGap和jQueryMobile构建适用于iOS和Android的跨平台HTML / Javascript应用程序,我正在使用本地数据库(localdatabase / websql)的一个表中的一些新字段(以及其他)升级我的应用程序。
挑战 我想确保在使用新表字段,现有用户数据扩展数据库时,不会删除用户数据或将其锁定在无法访问的旧版数据库中。
背景: 我的应用程序有一个用户数据的本地数据库(收入和支出,加上一些设置)。这些数据需要持久化,我开始时的方法是使用HTML5 localDatabase功能,因为它既是持久的,也适用于iOS和Android浏览器以及大多数桌面浏览器。
我正在使用一个名为persistenceJS的Javascript插件/库/ thingy来更轻松地处理localdb。但我的问题并不是特定于持久性.JS。
我正在开发一个新版本的应用程序,它使用了Settings表中的一些新字段。因此,当这些用户下载新应用并运行它时,它必须测试其“设置”表是否包含此字段,如果不是,则必须创建该字段。
我该如何进行测试?我看到两条思路:
使用openDatabase函数中使用的数据库标签....这似乎被一些开发人员用来存储版本号。 我对这个选项的麻烦是我只知道如何使用openDatabase打开数据库(如果不存在则创建一个新的数据库),并且如果数据库尚不存在则专门运行回调。 因此,如果我在标签中指定类似“v2”的东西时打开表格,它会创建一个新表吗?如果是这样,它会将旧表的值复制到新表中吗?
检查是否存在表格字段... 我可以使用openDatabase,然后测试表字段的存在。如果他们不这样做,我可以添加它们。每次用户打开他们的应用程序时都会运行测试,这似乎有点原始。
顺便说一下: 我知道webSQL / localDb已经被霸主弃用了,但它仍然是我的工具,我现在想坚持下去。
答案 0 :(得分:1)
我在这里找到答案:http://blog.maxaller.name/2010/03/html5-web-sql-database-intro-to-versioning-and-migrations/。
基本上,您只需将changeVersion方法应用于旧版本标签和新版本标签。如果您没有标签,则旧标签为“”。重新标记时,webSQL悄悄地将新模式应用于旧数据库。在我的情况下,这意味着添加新字段。
我链接到的教程非常棒(功能也是如此)。
答案 1 :(得分:1)
我正在添加另一个答案,因为我已经了解了有关localDb opendatabase的更多信息并进行了迁移。
提醒一下,openDatabase采用以下参数: name - (字符串)数据库的名称 version label - (字符串)要打开的版本 显示标签 - (字符串)一个看似无处可用的相当无用的显示名称 最大尺寸 - (int)最大安全尺寸为5 * 1024 * 1024 new created - =(function)如果db以前不存在则触发
将openDatabase的输出分配给变量是最明智的。即。
myapp.db = openDatabase('mydb','','我的数据库',5 * 1024 * 1024,newlyCreatedCallback);
首先,使用可以作为openDatabase的第五个参数的“新创建的”回调似乎是明智的。仅当没有包含您指定参数的数据库时,它才会触发。要防止在数据库已存在时触发此回调,请确保将名称,显示标签和最大大小设置为与首次创建数据库时使用的值完全相同。
这样做的原因是,如果首次创建数据库,您肯定知道不需要进行任何迁移。您可以直接进入添加表格和字段的功能。我建议使用persistenceJS,这是一个帮助您阅读和操作本地数据库的工具。
在调用openDatabase之前,最好使用jQuery创建一个自定义事件'dbopen',其处理程序将执行迁移。这个处理程序可以由两个事件触发。第一个是我们刚刚讨论过的“新创建的”回调。第二个是在调用openDatabase之后定义的setInterval。间隔必须检查是否存在您为openDatabase输出分配的myapp.db变量。
创建dbopen自定义事件的原因是,如果您添加了一个“新创建的”回调,它会触发一大堆事件并继续代码流,那么您将需要一个类似的过程来创建“非新创建的” '情景。 openDatabase没有回调来执行此操作,因此您必须手动检测本地数据库的创建并在它成立后立即触发'dbopen'。
我为此使用了window.setInterval。确保使用jquery的.one()函数创建自定义'dbopen'事件,该函数最多会触发一次。否则,如果数据库是新创建的,那么当“新创建的”回调触发时,以及myapp.db变量出现时,将触发open事件一次。