/* * Copyright (C) 2007-2015 FBReader.ORG Limited <contact@fbreader.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ package org.geometerplus.android.fbreader.config; import java.util.*; import android.app.Service; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteStatement; import org.geometerplus.android.fbreader.api.FBReaderIntents; final class SQLiteConfig extends ConfigInterface.Stub { private final Service myService; private final SQLiteDatabase myDatabase; private final SQLiteStatement myGetValueStatement; private final SQLiteStatement mySetValueStatement; private final SQLiteStatement myUnsetValueStatement; private final SQLiteStatement myDeleteGroupStatement; public SQLiteConfig(Service service) { myService = service; myDatabase = service.openOrCreateDatabase("config.db", Context.MODE_PRIVATE, null); switch (myDatabase.getVersion()) { case 0: myDatabase.execSQL("CREATE TABLE IF NOT EXISTS config (groupName VARCHAR, name VARCHAR, value VARCHAR, PRIMARY KEY(groupName, name) )"); break; case 1: myDatabase.beginTransaction(); SQLiteStatement removeStatement = myDatabase.compileStatement( "DELETE FROM config WHERE name = ? AND groupName LIKE ?" ); removeStatement.bindString(2, "/%"); removeStatement.bindString(1, "Size"); removeStatement.execute(); removeStatement.bindString(1, "Title"); removeStatement.execute(); removeStatement.bindString(1, "Language"); removeStatement.execute(); removeStatement.bindString(1, "Encoding"); removeStatement.execute(); removeStatement.bindString(1, "AuthorSortKey"); removeStatement.execute(); removeStatement.bindString(1, "AuthorDisplayName"); removeStatement.execute(); removeStatement.bindString(1, "EntriesNumber"); removeStatement.execute(); removeStatement.bindString(1, "TagList"); removeStatement.execute(); removeStatement.bindString(1, "Sequence"); removeStatement.execute(); removeStatement.bindString(1, "Number in seq"); removeStatement.execute(); myDatabase.execSQL( "DELETE FROM config WHERE name LIKE 'Entry%' AND groupName LIKE '/%'" ); myDatabase.setTransactionSuccessful(); myDatabase.endTransaction(); myDatabase.execSQL("VACUUM"); break; } myDatabase.setVersion(2); myGetValueStatement = myDatabase.compileStatement("SELECT value FROM config WHERE groupName = ? AND name = ?"); mySetValueStatement = myDatabase.compileStatement("INSERT OR REPLACE INTO config (groupName, name, value) VALUES (?, ?, ?)"); myUnsetValueStatement = myDatabase.compileStatement("DELETE FROM config WHERE groupName = ? AND name = ?"); myDeleteGroupStatement = myDatabase.compileStatement("DELETE FROM config WHERE groupName = ?"); } @Override synchronized public List<String> listGroups() { final LinkedList<String> list = new LinkedList<String>(); final Cursor cursor = myDatabase.rawQuery("SELECT DISTINCT groupName FROM config", null); while (cursor.moveToNext()) { list.add(cursor.getString(0)); } cursor.close(); return list; } @Override synchronized public List<String> listNames(String group) { final LinkedList<String> list = new LinkedList<String>(); final Cursor cursor = myDatabase.rawQuery("SELECT name FROM config WHERE groupName = ?", new String[] { group }); while (cursor.moveToNext()) { list.add(cursor.getString(0)); } cursor.close(); return list; } @Override synchronized public void removeGroup(String name) { myDeleteGroupStatement.bindString(1, name); try { myDeleteGroupStatement.execute(); } catch (SQLException e) { } } @Override synchronized public List<String> requestAllValuesForGroup(String group) { try { final List<String> pairs = new LinkedList<String>(); final Cursor cursor = myDatabase.rawQuery( "SELECT name,value FROM config WHERE groupName = ?", new String[] { group } ); while (cursor.moveToNext()) { pairs.add(cursor.getString(0) + "\000" + cursor.getString(1)); } cursor.close(); return pairs; } catch (SQLException e) { return Collections.emptyList(); } } @Override synchronized public String getValue(String group, String name) { myGetValueStatement.bindString(1, group); myGetValueStatement.bindString(2, name); try { return myGetValueStatement.simpleQueryForString(); } catch (SQLException e) { return null; } } @Override synchronized public void setValue(String group, String name, String value) { mySetValueStatement.bindString(1, group); mySetValueStatement.bindString(2, name); mySetValueStatement.bindString(3, value); try { mySetValueStatement.execute(); sendChangeEvent(group, name, value); } catch (SQLException e) { } } @Override synchronized public void unsetValue(String group, String name) { myUnsetValueStatement.bindString(1, group); myUnsetValueStatement.bindString(2, name); try { myUnsetValueStatement.execute(); sendChangeEvent(group, name, null); } catch (SQLException e) { } } private void sendChangeEvent(String group, String name, String value) { myService.sendBroadcast( new Intent(FBReaderIntents.Event.CONFIG_OPTION_CHANGE) .putExtra("group", group) .putExtra("name", name) .putExtra("value", value) ); } }