package im.actor.runtime.clc;
import java.sql.Connection;
import java.util.List;
import im.actor.runtime.storage.KeyValueRecord;
import im.actor.runtime.storage.KeyValueStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created by mohammad on 11/18/15.
*/
public class ClcKeyValueStorage implements KeyValueStorage {
private static final Logger logger = LoggerFactory.getLogger(ClcKeyValueStorage.class);
private SQLiteStatementWrapper insertStatement;
private SQLiteStatementWrapper deleteStatement;
private DBWrapper db;
private String name;
private boolean isSqliteChecked = false;
private String context;
/**
* Create table in keyvalue storage if does not exist
*
* @param db
* @param name table name
* @param context client unique identifier
*/
public ClcKeyValueStorage(Connection db, String name, String context) {
this.db = new DBWrapper(db);
this.name = name;
this.context = context;
if (context == null) {
logger.warn("context is not set");
this.context = "";
}
}
private void checkSqlite() {
if (!isSqliteChecked) {
isSqliteChecked = true;
db.execSQL("CREATE TABLE IF NOT EXISTS \"" + name + "\" (" + //
"\"ID\" INTEGER NOT NULL," + // 0: id
"\"BYTES\" BLOB NOT NULL," + // 1: bytes
"\"CONTEXT\" TEXT NOT NULL," + // 2: context
"PRIMARY KEY(\"ID\", \"CONTEXT\"));");
}
}
private void checkInsertStatement() {
if (insertStatement == null) {
insertStatement = db.compileStatement("INSERT OR REPLACE INTO \"" + name + "\" " +
"(\"ID\",\"BYTES\",\"CONTEXT\") VALUES (?,?,?)");
}
}
private void checkDeleteStatement() {
if (deleteStatement == null) {
deleteStatement = db.compileStatement("DELETE FROM \"" + name + "\" WHERE \"ID\"=? AND \"CONTEXT\"=? ");
}
}
@Override
public void addOrUpdateItem(long id, byte[] data) {
checkSqlite();
checkInsertStatement();
insertStatement.bindLong(1, id);
insertStatement.bindBlob(2, data);
insertStatement.bindString(3, this.context);
insertStatement.executeInsert();
}
@Override
public void addOrUpdateItems(List<KeyValueRecord> values) {
checkSqlite();
checkInsertStatement();
for (KeyValueRecord r : values) {
insertStatement.bindLong(1, r.getId());
insertStatement.bindBlob(2, r.getData());
insertStatement.bindString(3, this.context);
insertStatement.executeInsert();
}
}
@Override
public void removeItem(long id) {
checkSqlite();
checkDeleteStatement();
deleteStatement.bindLong(1, id);
deleteStatement.bindString(2, this.context);
deleteStatement.execute();
}
@Override
public void removeItems(long[] ids) {
checkSqlite();
checkDeleteStatement();
for (long id : ids) {
deleteStatement.bindLong(1, id);
deleteStatement.bindString(2, this.context);
deleteStatement.execute();
}
}
@Override
public byte[] loadItem(long key) {
checkSqlite();
Cursor cursor = db.query("\"" + name + "\"", new String[]{"\"BYTES\""}, "\"ID\" = ? AND \"CONTEXT\"='?' ", new String[]{"" + key, this.context}, null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToNext())
return cursor.getBlob("BYTES");
} finally {
cursor.close();
}
return null;
}
@Override
public List<KeyValueRecord> loadItems(long[] keys) {
return null;
}
@Override
public List<KeyValueRecord> loadAllItems() {
return null;
}
@Override
public void clear() {
checkSqlite();
db.execSQL("DELETE FROM \"" + name + "\"" + " WHERE \"CONTEXT\"='" + this.context + "'");
}
public void clearAll() {
checkSqlite();
db.execSQL("DELETE FROM \"" + name + "\"");
}
public String getContext() {
return this.context;
}
}