package com.shunzhi.parent.dbhelper; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.support.annotation.StringDef; import android.text.TextUtils; import android.util.Log; import com.shunzhi.parent.dbhelper.utils.IOUtils; import com.shunzhi.parent.dbhelper.utils.NaturalOrderComparator; import com.shunzhi.parent.dbhelper.utils.SqlParser; import org.greenrobot.greendao.database.Database; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.Collections; import java.util.List; import timber.log.Timber; public class DBUpdateHelper { private Context context; public final static String SQL_PARSER_LEGACY = "legacy"; public final static String SQL_PARSER_DELIMITED = "delimited"; private final String mSqlParser; @StringDef({SQL_PARSER_DELIMITED, SQL_PARSER_LEGACY}) @Retention(RetentionPolicy.SOURCE) public @interface SQLParser { } public DBUpdateHelper(Context context, @SQLParser String sqlParser) { this.context = context.getApplicationContext(); mSqlParser = sqlParser; } public boolean onUpdate(Database db, int oldVersion, int newVersion) { return executeMigrations(db, oldVersion, newVersion); } private boolean executeMigrations(Database db, int oldVersion, int newVersion) { boolean migrationExecuted = false; try { final List files = Arrays.asList(context.getAssets().list("migrations")); Collections.sort(files, new NaturalOrderComparator()); db.beginTransaction(); try { for (String file : files) { try { final int version = Integer.valueOf(file.replace(".sql", "")); if (version > oldVersion && version <= newVersion) { executeSqlScript(db, file); migrationExecuted = true; Timber.i("---==="+file + " executed succesfully."); } } catch (NumberFormatException e) { e.printStackTrace(); } } db.setTransactionSuccessful(); } finally { db.endTransaction(); } } catch (IOException e) { e.printStackTrace(); } return migrationExecuted; } private final static String MIGRATION_PATH = "migrations"; private void executeSqlScript(Database db, String file) { InputStream stream = null; try { stream = context.getAssets().open(MIGRATION_PATH + "/" + file); //因为我懒,不允许自定义解析方式 //算了,还是加上吧 突然忘了类型限定怎么写了 就当练练手 if (SQL_PARSER_DELIMITED.equalsIgnoreCase(mSqlParser)) { executeDelimitedSqlScript(db, stream); } else { executeLegacySqlScript(db, stream); } } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(stream); } } private void executeDelimitedSqlScript(Database db, InputStream stream) throws IOException { List commands = SqlParser.parse(stream); for (String command : commands) { db.execSQL(command); } } private void executeLegacySqlScript(Database db, InputStream stream) throws IOException { InputStreamReader reader = null; BufferedReader buffer = null; try { reader = new InputStreamReader(stream); buffer = new BufferedReader(reader); String line = null; while ((line = buffer.readLine()) != null) { line = line.replace(";", "").trim(); if (!TextUtils.isEmpty(line)) { db.execSQL(line); } } } finally { IOUtils.closeQuietly(buffer); IOUtils.closeQuietly(reader); } } }