/** * Copyright 2008 - 2015 The Loon Game Engine Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.5 */ package loon.robovm; import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import loon.Save; import loon.SaveBatchImpl; import org.robovm.apple.foundation.NSFileManager; import org.robovm.apple.foundation.NSSearchPathDirectory; import org.robovm.apple.foundation.NSSearchPathDomainMask; public class RoboVMSave implements Save { private final RoboVMGame game; private final Connection conn; public RoboVMSave(RoboVMGame game) { this.game = game; String dbDir = null; try { try { Class.forName("SQLite.JDBCDriver"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } dbDir = NSFileManager.getDefaultManager().getURLsForDirectory( NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask).get(0).getPath(); File dbFile = new File(dbDir, game.config.storageFileName); dbFile.getParentFile().mkdirs(); game.log().info("Using db in file: " + dbFile.getAbsolutePath()); conn = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getAbsolutePath()); try (Statement stmt = conn.createStatement()) { stmt.executeUpdate("CREATE TABLE IF NOT EXISTS " + "Data (DataKey ntext PRIMARY KEY, DataValue ntext NOT NULL)"); } } catch (SQLException sqe) { throw new RuntimeException("Failed to initialize storage [dbDir=" + dbDir + "]", sqe); } } @Override public boolean isPersisted() { return true; } @Override public Iterable<String> keys() { try { List<String> keys = new ArrayList<String>(); try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery("select DataKey from Data"); while (rs.next()) { keys.add(rs.getString(1)); } } return keys; } catch (SQLException sqe) { throw new RuntimeException("keys() failed", sqe); } } @Override public String getItem(String key) { try { String sql = "select DataValue from Data where DataKey = ?"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, key); ResultSet rs = stmt.executeQuery(); String result = null; while (rs.next()) { result = rs.getString(1); } return result; } } catch (SQLException sqe) { throw new RuntimeException("getItem(" + key + ") failed", sqe); } } @Override public void setItem(String key, String value) throws RuntimeException { try { String usql = "update Data set DataValue = ? where DataKey = ?"; try (PreparedStatement ustmt = conn.prepareStatement(usql)) { ustmt.setString(1, value); ustmt.setString(2, key); if (ustmt.executeUpdate() > 0) return; } String isql = "insert into Data (DataKey, DataValue) values (?, ?)"; try (PreparedStatement istmt = conn.prepareStatement(isql)) { istmt.setString(1, key); istmt.setString(2, value); if (istmt.executeUpdate() == 0) { game.log().warn("Failed to insert storage item [key=" + key + "]"); } } } catch (SQLException sqe) { throw new RuntimeException("setItem(" + key + ", " + value + ") failed", sqe); } } @Override public void removeItem(String key) { try { String sql = "delete from Data where DataKey = ?"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, key); stmt.executeUpdate(); } } catch (SQLException sqe) { throw new RuntimeException("removeItem(" + key + ") failed", sqe); } } @Override public Batch startBatch() { return new SaveBatchImpl(this); } }