Last active
December 4, 2015 17:43
-
-
Save anzfactory/8b06414037df9ed1bf62 to your computer and use it in GitHub Desktop.
SQLite差分アップデート(SQLiteUnityKit版)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************* | |
SQLiteのdbを差分アップデートする奴 | |
2015-12-04 | |
*********************************/ | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class SqliteMigration | |
{ | |
private SqliteDatabase dbInstance; | |
private string dbPath; | |
public SqliteMigration(SqliteDatabase db, string path) | |
{ | |
this.dbInstance = db; | |
this.dbPath = path; | |
} | |
public void Migrate() | |
{ | |
// 現在のDBバージョンを読み込む | |
int currentVersion = GetCurrentVersion(); | |
Debug.Log("current db version:" + currentVersion); | |
// 差分アップデート用のファイルがあるかサーチ | |
var sqlList = SearchMigrateSql(currentVersion); | |
if (sqlList.Count == 0) { | |
// アップデート必要なし | |
Debug.Log("cancel migrate"); | |
return; | |
} | |
Debug.Log("do migrate files:" + sqlList.Count); | |
// version 順に適用していかないと矛盾が生じる可能性があるので昇順ソート | |
var versions = new List<int>(sqlList.Keys); | |
versions.Sort(); | |
// バックアップをとっておく | |
string backupPath = Backup(); | |
Debug.Log("backup path:" + backupPath); | |
try { | |
string sql = ""; | |
foreach (int ver in versions) { | |
sql = sqlList[ver]; | |
this.dbInstance.ExecuteScript(sql); | |
} | |
// 最後にバージョンアップ(最終バージョンに) | |
sql = string.Format("update `version_info` set `version` = {0}", Last<int>(versions.ToArray())); | |
this.dbInstance.ExecuteNonQuery(sql); | |
} catch (System.Exception e) { | |
// リストア | |
Restore(backupPath); | |
// 失敗したら普通にアプリ実行させたところでアカンので終了 | |
// TODO なんかアラートとかだしたいけど... | |
// throw e; 例外スローしてもアプリおちないので.... | |
Application.Quit(); // 自分でおとす | |
} | |
} | |
private int GetCurrentVersion() | |
{ | |
string sql = "select `version` from `version_info`"; | |
var dt = this.dbInstance.ExecuteQuery(sql); | |
if (dt == null || dt.Rows.Count == 0) { | |
throw new SqliteMigrationException("DBにバージョン情報が存在しないようです"); | |
} | |
return int.Parse(dt.Rows[0]["version"].ToString()); | |
} | |
private Dictionary<int, string> SearchMigrateSql(int currentVersion) | |
{ | |
Dictionary<int, string> sqlList = new Dictionary<int, string>(); | |
int searchVersion = currentVersion; | |
searchVersion++; | |
string sql = ""; | |
// .sqlファイル検索する | |
while (ReadFile(searchVersion, out sql)) { | |
sqlList.Add(searchVersion, sql); | |
searchVersion++; | |
} | |
return sqlList; | |
} | |
private string Backup() | |
{ | |
string tempPath = System.IO.Path.Combine(Application.temporaryCachePath, "backup.db"); | |
if (this.dbPath.Contains("://") || tempPath.Contains("://")) { | |
WWW www = new WWW(this.dbPath); | |
while (!www.isDone) { | |
// 待機 | |
} | |
System.IO.File.WriteAllBytes(tempPath, www.bytes); | |
} else { | |
System.IO.File.Copy(this.dbPath, tempPath, true); // 第3引数は上書可能かどうか | |
} | |
return tempPath; | |
} | |
private void Restore(string backupPath) | |
{ | |
if (this.dbPath.Contains("://") || backupPath.Contains("://")) { | |
WWW www = new WWW(backupPath); | |
while (!www.isDone) { | |
// 待機 | |
} | |
System.IO.File.WriteAllBytes(this.dbPath, www.bytes); | |
} else { | |
// バックアップファイルから上書き | |
System.IO.File.Copy(backupPath, this.dbPath, true); // 第3引数は上書可能かどうか | |
} | |
} | |
private bool ReadFile(int searchVersion, out string sql) | |
{ | |
string path = System.IO.Path.Combine( | |
Application.streamingAssetsPath, | |
searchVersion.ToString() + ".sql" | |
); | |
Debug.Log(path); | |
if (path.Contains("://")) { | |
// Android だと System.IOでよみこめないのでwww使うみたい | |
// http://answers.unity3d.com/questions/210909/android-streamingassets-file-access.html | |
sql = ReadFileByWWW(path); | |
} else { | |
sql = ReadFileByIO(path); | |
} | |
return !string.IsNullOrEmpty(sql); | |
} | |
private string ReadFileByWWW(string path) | |
{ | |
WWW www = new WWW(path); | |
while (!www.isDone) { | |
// 読み込みが終わるまで待機 | |
} | |
string text = ""; | |
if (string.IsNullOrEmpty(www.error)) { | |
text = www.text; | |
} else { | |
Debug.Log(www.error); | |
} | |
return text; | |
} | |
private string ReadFileByIO(string path) | |
{ | |
string text = ""; | |
if (System.IO.File.Exists(path)) { | |
text = System.IO.File.ReadAllText(path); | |
} | |
return text; | |
} | |
private T Last<T>(T[] arr) | |
{ | |
if (arr == null || arr.Length == 0) { | |
return default(T); | |
} | |
return arr[arr.Length - 1]; | |
} | |
} | |
public class SqliteMigrationException : System.Exception | |
{ | |
public SqliteMigrationException (string message) : base(message) | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment