From 1e59ed663f5fc022233b6f2e29ee3ecc0b226259 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maty=C3=A1=C5=A1=20Latner?= <matyas.latner@nic.cz>
Date: Wed, 20 May 2015 13:58:01 +0200
Subject: [PATCH] #25 Storage access code refactoring. Test code for iOS
 platform

---
 .../nic/tablexia/android/AndroidLauncher.java |   9 +-
 core/src/cz/nic/tablexia/Tablexia.java        |  41 +++++--
 core/src/cz/nic/tablexia/TablexiaStorage.java |  72 +++++++++++
 .../nic/tablexia/persist/SqliteStorage.java   | 116 ------------------
 .../tablexia/screen/loader/LoaderScreen.java  |  21 ++++
 .../nic/tablexia/desktop/DesktopLauncher.java |   8 +-
 ios/src/cz/nic/tablexia/IOSLauncher.java      |   9 +-
 7 files changed, 148 insertions(+), 128 deletions(-)
 create mode 100644 core/src/cz/nic/tablexia/TablexiaStorage.java
 delete mode 100644 core/src/cz/nic/tablexia/persist/SqliteStorage.java

diff --git a/android/src/cz/nic/tablexia/android/AndroidLauncher.java b/android/src/cz/nic/tablexia/android/AndroidLauncher.java
index 0ba59c0a5..fe6b3e9e5 100644
--- a/android/src/cz/nic/tablexia/android/AndroidLauncher.java
+++ b/android/src/cz/nic/tablexia/android/AndroidLauncher.java
@@ -9,10 +9,17 @@ import cz.nic.tablexia.Tablexia;
 import cz.nic.tablexia.debug.BuildConfig;
 
 public class AndroidLauncher extends AndroidApplication {
+
+	public static final Tablexia.SQLConnectionType SQL_CONNECTION_TYPE = new Tablexia.SQLConnectionType("org.sqldroid.SQLDroidDriver", "jdbc:sqldroid:");
+
 	@Override
 	protected void onCreate (Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
-        initialize(new Tablexia(BuildConfig.BUILD_TYPE, getResources().getConfiguration().locale, BuildConfig.VERSION_NAME, savedInstanceState == null), config);
+        initialize(new Tablexia(BuildConfig.BUILD_TYPE,
+								getResources().getConfiguration().locale,
+								BuildConfig.VERSION_NAME,
+								SQL_CONNECTION_TYPE,
+								savedInstanceState == null), config);
 	}
 }
diff --git a/core/src/cz/nic/tablexia/Tablexia.java b/core/src/cz/nic/tablexia/Tablexia.java
index 0bf3078dc..ab445eaa8 100644
--- a/core/src/cz/nic/tablexia/Tablexia.java
+++ b/core/src/cz/nic/tablexia/Tablexia.java
@@ -16,7 +16,6 @@ import cz.nic.tablexia.loader.application.ApplicationTextManager;
 import cz.nic.tablexia.loader.application.ApplicationTextureManager;
 import cz.nic.tablexia.loader.zip.ZipAssetLoader;
 import cz.nic.tablexia.menu.MainMenuContainer;
-import cz.nic.tablexia.persist.SqliteStorage;
 import cz.nic.tablexia.screen.AbstractTablexiaScreen;
 import cz.nic.tablexia.screen.loader.LoaderScreen;
 import cz.nic.tablexia.util.Log;
@@ -24,19 +23,41 @@ import cz.nic.tablexia.util.Utility;
 
 public class Tablexia extends TablexiaApplication {
 
-    private boolean             loadingComplete = false;
-    private MainMenuContainer   mainMenuContainer;
-    private ZipAssetLoader      zipAssetLoader;
-    private boolean             resetState;
+    private final SQLConnectionType     sqlConnectionType;
+    private boolean                     loadingComplete = false;
+    private MainMenuContainer           mainMenuContainer;
+    private ZipAssetLoader              zipAssetLoader;
+    private boolean                     resetState;
 
-    public Tablexia(boolean debug, Locale systemLocale, String versionName, boolean resetState) {
+    public static class SQLConnectionType {
+
+        private String driver;
+        private String connectionString;
+
+        public SQLConnectionType(String driver, String connectionString) {
+            this.driver = driver;
+            this.connectionString = connectionString;
+        }
+
+        public String getDriver() {
+            return driver;
+        }
+
+        public String getConnectionString() {
+            return connectionString;
+        }
+    }
+
+    public Tablexia(boolean debug, Locale systemLocale, String versionName, SQLConnectionType sqlConnectionType, boolean resetState) {
         TablexiaSettings.init(debug, systemLocale, versionName);
         this.resetState = resetState;
+        this.sqlConnectionType = sqlConnectionType;
     }
 
-    public Tablexia(String buildTypeKey, Locale systemLocale, String versionName, boolean resetState) {
+    public Tablexia(String buildTypeKey, Locale systemLocale, String versionName, SQLConnectionType sqlConnectionType, boolean resetState) {
         TablexiaSettings.init(buildTypeKey, systemLocale, versionName);
         this.resetState = resetState;
+        this.sqlConnectionType = sqlConnectionType;
     }
 
     private void loadingComplete() {
@@ -117,12 +138,13 @@ public class Tablexia extends TablexiaApplication {
 
         TablexiaSettings.getInstance().loadPreferences(resetState);
         Log.setLoglevel(TablexiaSettings.getInstance().getLogLevel());
+
+        // init data storage
+        TablexiaStorage.init(sqlConnectionType);
 		
 		// init event bus handlers
 		ApplicationBus.getInstance().subscribe(this);
 
-        SqliteStorage.storageTest();
-
         // start loading application scope data
         startLoading(TablexiaSettings.getInstance().getLocale());
     }
@@ -159,6 +181,7 @@ public class Tablexia extends TablexiaApplication {
     @Override
     public void dispose() {
         super.dispose();
+        TablexiaStorage.getInstance().dispose();
         clearLoadedData();
     }
 
diff --git a/core/src/cz/nic/tablexia/TablexiaStorage.java b/core/src/cz/nic/tablexia/TablexiaStorage.java
new file mode 100644
index 000000000..3ee38a3ba
--- /dev/null
+++ b/core/src/cz/nic/tablexia/TablexiaStorage.java
@@ -0,0 +1,72 @@
+package cz.nic.tablexia;
+
+import com.badlogic.gdx.Gdx;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import cz.nic.tablexia.loader.TablexiaAssetManager;
+import cz.nic.tablexia.util.Log;
+
+/**
+ * Created by Matyáš Latner.
+ */
+public class TablexiaStorage {
+
+    public static final String DATABASE_DIRECTORY = Gdx.files.getExternalStoragePath() + TablexiaAssetManager.StorageType.EXTERNAL.getStoragePath();
+    public static final String DATABASE_NAME = "tablexia.db";
+
+    private static  TablexiaStorage instance = null;
+    private         Connection      connection = null;
+
+    private TablexiaStorage(Connection connection) {
+        this.connection = connection;
+    }
+
+    static void init(Tablexia.SQLConnectionType connectionType) {
+        if (instance == null) {
+            try {
+                Class.forName(connectionType.getDriver());
+                Connection connection = DriverManager.getConnection(connectionType.getConnectionString() + DATABASE_DIRECTORY + "/" + DATABASE_NAME);
+                instance = new TablexiaStorage(connection);
+            } catch (ClassNotFoundException e) {
+                Log.err(TablexiaStorage.class, "Cannot find class for database driver!", e);
+            } catch (SQLException e) {
+                Log.err(TablexiaStorage.class, "Cannot create database connection!", e);
+            }
+        } else {
+            throw new IllegalStateException("Data storage already initialized!");
+        }
+    }
+
+    void dispose() {
+        if (connection != null) {
+            try {
+                connection.close();
+            } catch (SQLException e) {
+                Log.err(getClass(), "Cannot close connection!", e);
+                e.printStackTrace();
+            }
+        } else {
+            throw new IllegalStateException("Data storage is not initialized or already closed!");
+        }
+    }
+
+    public static TablexiaStorage getInstance() {
+        if (instance == null) {
+            throw new IllegalStateException("Data storage is not initialized!");
+        }
+        return instance;
+    }
+
+    public Statement createStatement() {
+        try {
+            return connection.createStatement();
+        } catch (SQLException e) {
+            Log.err(getClass(), "Cannot create statement!", e);
+            return null;
+        }
+    }
+}
diff --git a/core/src/cz/nic/tablexia/persist/SqliteStorage.java b/core/src/cz/nic/tablexia/persist/SqliteStorage.java
deleted file mode 100644
index e484e1416..000000000
--- a/core/src/cz/nic/tablexia/persist/SqliteStorage.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package cz.nic.tablexia.persist;
-
-import com.badlogic.gdx.Application;
-import com.badlogic.gdx.Gdx;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import cz.nic.tablexia.loader.TablexiaAssetManager;
-import cz.nic.tablexia.util.Log;
-
-/**
- * Created by matyas on 18.5.15.
- */
-public class SqliteStorage {
-
-    private enum SQLDriverType {
-
-        DESKTOP (Application.ApplicationType.Desktop,   "org.sqlite.JDBC", "jdbc:sqlite:"),
-        ANDROID (Application.ApplicationType.Android,   "org.sqldroid.SQLDroidDriver", "jdbc:sqldroid:"),
-        IOS     (Application.ApplicationType.iOS,       "SQLite.JDBCDriver", "jdbc:sqlite:");
-
-        private Application.ApplicationType applicationType;
-        private String driverName;
-        private String databaseConnection;
-
-        SQLDriverType(Application.ApplicationType applicationType, String driverName, String databaseConnection) {
-            this.applicationType = applicationType;
-            this.driverName = driverName;
-            this.databaseConnection = databaseConnection;
-        }
-
-        public static String getDriverNameForApplicationType(Application.ApplicationType applicationType) {
-            for (SQLDriverType driverType : SQLDriverType.values()) {
-                if (driverType.applicationType == applicationType) {
-                    return driverType.driverName;
-                }
-            }
-            return null;
-        }
-
-        public static String getDatabseConnectionForApplicationType(Application.ApplicationType applicationType) {
-            for (SQLDriverType driverType : SQLDriverType.values()) {
-                if (driverType.applicationType == applicationType) {
-                    return driverType.databaseConnection;
-                }
-            }
-            return null;
-        }
-    }
-
-    public static void storageTest() {
-
-
-
-        Log.debug(SqliteStorage.class, "------->> POKUS");
-
-        String dbDirectory = Gdx.files.getExternalStoragePath() + TablexiaAssetManager.StorageType.EXTERNAL.getStoragePath();
-        String dbFileName = "tablexia.db";
-        String dbPath = dbDirectory + "/" + dbFileName;
-
-        // load the sqlite-JDBC driver using the current class loader
-        try {
-            //Class.forName("org.sqlite.JDBC");
-            Class.forName(SQLDriverType.getDriverNameForApplicationType(Gdx.app.getType()));
-        } catch (ClassNotFoundException e) {
-            e.printStackTrace();
-        }
-
-        Connection connection = null;
-        try
-        {
-            // create a database connection
-            connection = DriverManager.getConnection(SQLDriverType.getDatabseConnectionForApplicationType(Gdx.app.getType()) + dbPath);
-            Statement statement = connection.createStatement();
-            //statement.setQueryTimeout(30);  // set timeout to 30 sec.
-
-            Log.debug(SqliteStorage.class, "------->> POKUS2");
-
-            statement.executeUpdate("drop table if exists person");
-            statement.executeUpdate("create table person (id integer, name string)");
-            statement.executeUpdate("insert into person values(1, 'leo')");
-            statement.executeUpdate("insert into person values(2, 'yui')");
-            ResultSet rs = statement.executeQuery("select * from person");
-            while(rs.next())
-            {
-                // read the result set
-                System.out.println("name = " + rs.getString("name"));
-                System.out.println("id = " + rs.getInt("id"));
-            }
-        }
-        catch(SQLException e)
-        {
-            // if the error message is "out of memory",
-            // it probably means no database file is found
-            e.printStackTrace();
-        }
-        finally
-        {
-            Log.debug(SqliteStorage.class, "------->> POKUS3");
-            try
-            {
-                if(connection != null)
-                    connection.close();
-            }
-            catch(SQLException e)
-            {
-                // connection close failed.
-                System.err.println(e);
-            }
-        }
-    }
-}
diff --git a/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java b/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java
index 72b1cbfce..360e5ed2a 100644
--- a/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java
+++ b/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java
@@ -4,9 +4,13 @@ import com.badlogic.gdx.graphics.Texture;
 import com.badlogic.gdx.scenes.scene2d.actions.Actions;
 import com.badlogic.gdx.scenes.scene2d.ui.Image;
 
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
 import java.util.List;
 
 import cz.nic.tablexia.TablexiaSettings;
+import cz.nic.tablexia.TablexiaStorage;
 import cz.nic.tablexia.loader.TablexiaAssetManager;
 import cz.nic.tablexia.screen.AbstractLinearTextureTablexiaScreen;
 
@@ -48,6 +52,23 @@ public class LoaderScreen extends AbstractLinearTextureTablexiaScreen<Void> {
         getStage().addActor(bighand);
         bighand.setOrigin(bighand.getWidth() / 2, 5);
         bighand.addAction(Actions.forever(Actions.rotateBy(-360, 0.5f)));
+
+
+        Statement statement = TablexiaStorage.getInstance().createStatement();
+        try {
+            statement.executeUpdate("drop table if exists person");
+            statement.executeUpdate("create table person (id integer, name string)");
+            statement.executeUpdate("insert into person values(1, 'leo')");
+            statement.executeUpdate("insert into person values(2, 'yui')");
+            ResultSet rs = statement.executeQuery("select * from person");
+            while(rs.next()) {
+                // read the result set
+                System.out.println("name = " + rs.getString("name"));
+                System.out.println("id = " + rs.getInt("id"));
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
     }
 
     @Override
diff --git a/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java b/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java
index e9bbd1056..6a62b6402 100644
--- a/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java
+++ b/desktop/src/cz/nic/tablexia/desktop/DesktopLauncher.java
@@ -26,6 +26,8 @@ public class DesktopLauncher {
     private static final String DESKTOP_ICON_DEVEL_32                = DESKTOP_ICON_PATH + "desktop_icon_devel_32.png";
     private static final String DESKTOP_ICON_DEVEL_128               = DESKTOP_ICON_PATH + "desktop_icon_devel_128.png";
 
+    public static final Tablexia.SQLConnectionType SQL_CONNECTION_TYPE = new Tablexia.SQLConnectionType("org.sqlite.JDBC", "jdbc:sqlite:");
+
     public static void main(String[] arg) {
 
         String buildType = loadAttributeFromManifest(BUILD_VARIANT_MANIFEST_ATTRIBUTE);
@@ -50,7 +52,11 @@ public class DesktopLauncher {
             config.addIcon(DESKTOP_ICON_128, Files.FileType.Internal);
         }
 
-	    new LwjglApplication(new Tablexia(buildType, Locale.getDefault(), versionName, true), config);
+	    new LwjglApplication(new Tablexia(buildType,
+                                          Locale.getDefault(),
+                                          versionName,
+                                          SQL_CONNECTION_TYPE,
+                                          true), config);
     }
 
     private static String loadAttributeFromManifest(String attributeName) {
diff --git a/ios/src/cz/nic/tablexia/IOSLauncher.java b/ios/src/cz/nic/tablexia/IOSLauncher.java
index 44c0ce49a..1e51c84fa 100644
--- a/ios/src/cz/nic/tablexia/IOSLauncher.java
+++ b/ios/src/cz/nic/tablexia/IOSLauncher.java
@@ -12,6 +12,9 @@ import org.robovm.apple.uikit.UIApplication;
 import java.util.Locale;
 
 public class IOSLauncher extends IOSApplication.Delegate {
+
+    public static final Tablexia.SQLConnectionType SQL_CONNECTION_TYPE = new Tablexia.SQLConnectionType("SQLite.JDBCDriver", "jdbc:sqlite:");
+
     @Override
     protected IOSApplication createApplication() {
         IOSApplicationConfiguration config = new IOSApplicationConfiguration();
@@ -21,7 +24,11 @@ public class IOSLauncher extends IOSApplication.Delegate {
         String versionName = infoDictionary.get(new NSString("CFBundleShortVersionString")).toString();
 
         //TODO check application state
-        return new IOSApplication(new Tablexia(buildType, Locale.getDefault(), versionName, false), config);
+        return new IOSApplication(new Tablexia(buildType,
+                                               Locale.getDefault(),
+                                               versionName,
+                                               SQL_CONNECTION_TYPE,
+                                               false), config);
     }
 
     public static void main(String[] argv) {
-- 
GitLab