@Override
  public final void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    Log.w(
        TAG,
        "Upgrading database "
            + mName
            + " from version "
            + oldVersion
            + " to "
            + newVersion
            + "...");

    ArrayList<String> paths = new ArrayList<String>();
    getUpgradeFilePaths(oldVersion, newVersion - 1, newVersion, paths);

    if (paths.isEmpty()) {
      Log.e(TAG, "no upgrade script path from " + oldVersion + " to " + newVersion);
      throw new SQLiteAssetException(
          "no upgrade script path from " + oldVersion + " to " + newVersion);
    }

    Collections.sort(paths);
    for (String path : paths) {
      try {
        Log.w(TAG, "processing upgrade: " + path);
        InputStream is = mContext.getAssets().open(path);
        String sql = convertStreamToString(is);
        if (sql != null) {
          String[] cmds = sql.split(";");
          for (String cmd : cmds) {
            // Log.d(TAG, "cmd=" + cmd);
            if (isValidCmd(cmd)) {
              db.execSQL(cmd);
            }
          }
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    Log.w(
        TAG,
        "Successfully upgraded database "
            + mName
            + " from version "
            + oldVersion
            + " to "
            + newVersion);
  }
  private void getUpgradeFilePaths(int baseVersion, int start, int end, ArrayList<String> paths) {

    int a;
    int b;

    InputStream is = getUpgradeSQLStream(start, end);
    if (is != null) {
      String path = String.format(mUpgradePathFormat, start, end);
      paths.add(path);
      // Log.d(TAG, "found script: " + path);
      a = start - 1;
      b = start;
      is = null;
    } else {
      a = start - 1;
      b = end;
    }

    if (a < baseVersion) {
      return;
    } else {
      getUpgradeFilePaths(baseVersion, a, b, paths); // recursive call
    }
  }