- 7.0.0-rc.8
+ 7.0.0-rc.9
2.11.2
diff --git a/kripton-orm/src/main/java/com/abubusoft/kripton/android/sqlcipher/Database.java b/kripton-orm/src/main/java/com/abubusoft/kripton/android/sqlcipher/Database.java
index 2a7e213d6..a53aef119 100644
--- a/kripton-orm/src/main/java/com/abubusoft/kripton/android/sqlcipher/Database.java
+++ b/kripton-orm/src/main/java/com/abubusoft/kripton/android/sqlcipher/Database.java
@@ -261,13 +261,9 @@ public Cursor query(final SupportSQLiteQuery supportQuery, CancellationSignal si
supportQuery.bindTo(hack);
- return (safeDb.rawQueryWithFactory(new net.sqlcipher.database.SQLiteDatabase.CursorFactory() {
- @Override
- public net.sqlcipher.Cursor newCursor(net.sqlcipher.database.SQLiteDatabase db,
- SQLiteCursorDriver masterQuery, String editTable, SQLiteQuery query) {
- supportQuery.bindTo(new Program(query));
- return new SQLiteCursor(db, masterQuery, editTable, query);
- }
+ return (safeDb.rawQueryWithFactory((db, masterQuery, editTable, query) -> {
+ supportQuery.bindTo(new Program(query));
+ return new SQLiteCursor(db, masterQuery, editTable, query);
}, supportQuery.getSql(), hack.getBindings(), null));
}
diff --git a/kripton-orm/src/main/java/com/abubusoft/kripton/android/sqlite/AbstractDataSource.java b/kripton-orm/src/main/java/com/abubusoft/kripton/android/sqlite/AbstractDataSource.java
index b6861815a..c0422290d 100644
--- a/kripton-orm/src/main/java/com/abubusoft/kripton/android/sqlite/AbstractDataSource.java
+++ b/kripton-orm/src/main/java/com/abubusoft/kripton/android/sqlite/AbstractDataSource.java
@@ -1,38 +1,23 @@
-/*******************************************************************************
+/**
* Copyright 2015, 2017 Francesco Benincasa (info@abubusoft.com).
- *
+ *
* 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
- *
+ *
+ * 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.
- *******************************************************************************/
+ */
/**
- *
+ *
*/
package com.abubusoft.kripton.android.sqlite;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import com.abubusoft.kripton.android.KriptonLibrary;
-import com.abubusoft.kripton.android.Logger;
-import com.abubusoft.kripton.common.Pair;
-import com.abubusoft.kripton.exception.KriptonRuntimeException;
-
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
@@ -42,6 +27,20 @@
import androidx.sqlite.db.SupportSQLiteOpenHelper;
import androidx.sqlite.db.SupportSQLiteOpenHelper.Configuration.Builder;
import androidx.sqlite.db.SupportSQLiteStatement;
+import com.abubusoft.kripton.android.KriptonLibrary;
+import com.abubusoft.kripton.android.Logger;
+import com.abubusoft.kripton.common.Pair;
+import com.abubusoft.kripton.exception.KriptonRuntimeException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
*
@@ -53,855 +52,846 @@
*/
public abstract class AbstractDataSource implements AutoCloseable {
- /**
- * Interface for database operations.
- *
- * @param
- * the element type
- */
- public interface AbstractExecutable {
-
- /**
- * Execute transation. Method need to return
- * {@link TransactionResult#COMMIT} to commit results or
- * {@link TransactionResult#ROLLBACK} to rollback. If exception is
- * thrown, a rollback will be done.
- *
- * @param daoFactory
- * the dao factory
- * @return the transaction result
- */
- TransactionResult onExecute(E daoFactory);
- }
-
- /**
- * The listener interface for receiving onError events. The class that is
- * interested in processing a onError event implements this interface, and
- * the object created with that class is registered with a component using
- * the component's addOnErrorListener
method. When the onError
- * event occurs, that object's appropriate method is invoked.
- *
- */
- public interface OnErrorListener {
- /**
- * Manages error situations.
- *
- * @param e
- * exception
- */
- void onError(Throwable e);
- }
-
- /**
- * The Enum TypeStatus.
- */
- public enum TypeStatus {
-
- /** The closed. */
- CLOSED,
- /** The read and write opened. */
- READ_AND_WRITE_OPENED,
- /** The read only opened. */
- READ_ONLY_OPENED
- }
-
- /** The context. */
- protected SQLContextImpl context;
-
- /** database instance. */
- SupportSQLiteDatabase database;
-
- /**
- *
- * True if dataSource is just created
- *
- * .
- */
- protected boolean justCreated = false;
-
- /** The lock access. */
- private final ReentrantReadWriteLock lockAccess = new ReentrantReadWriteLock();
-
- /** The lock db. */
- private final ReentrantLock lockDb = new ReentrantLock();
-
- /** The lock read access. */
- private final Lock lockReadAccess = lockAccess.readLock();
-
- /** The lock read write access. */
- private final Lock lockReadWriteAccess = lockAccess.writeLock();
-
- /** The log enabled. */
- protected boolean logEnabled;
-
- /**
- *
- * file name used to save database,
- *
- * .
- */
- protected final String name;
-
- /** The on error listener. */
- protected OnErrorListener onErrorListener = (Throwable e) -> { throw (new KriptonRuntimeException(e));};
-
-
- /** The open counter. */
- private AtomicInteger openCounter = new AtomicInteger();
-
- /** The options. */
- protected DataSourceOptions options;
-
- /** The sqlite helper. */
- protected SupportSQLiteOpenHelper sqliteHelper;
-
- /** The status. */
- protected ThreadLocal status = new ThreadLocal() {
-
- @Override
- protected TypeStatus initialValue() {
- return TypeStatus.CLOSED;
- }
-
- };
-
- /**
- *
- * database version
- *
- * .
- */
- protected int version;
-
- /** if true, database was update during this application run. */
- protected boolean versionChanged;
-
- /**
- * Instantiates a new abstract data source.
- *
- * @param name
- * the name
- * @param version
- * the version
- * @param options
- * the options
- */
- protected AbstractDataSource(String name, int version, DataSourceOptions options) {
- DataSourceOptions optionsValue = (options == null) ? DataSourceOptions.builder().build() : options;
-
- this.name = optionsValue.inMemory ? null : name;
- this.version = version;
-
- // create new SQLContext
- this.context = new SQLContextImpl(this);
-
- this.options = optionsValue;
- this.logEnabled = optionsValue.logEnabled;
-
- if (this.logEnabled) {
- Logger.debug("%s is created with %s", getClass().getName(), options.toString());
- }
- }
-
- protected void beginLock() {
- lockDb.lock();
- }
-
- /**
- * Builds the task list.
- *
- * @param previousVersion
- * the previous version
- * @param currentVersion
- * the current version
- * @return the list
- */
- protected List buildTaskList(int previousVersion, int currentVersion) {
- List result = new ArrayList<>();
-
- for (Pair item : this.options.updateTasks) {
- if (item.value0 - 1 == previousVersion) {
- result.add(item.value1);
- previousVersion = item.value0;
- }
-
- if (previousVersion == currentVersion)
- break;
- }
-
- if (previousVersion != currentVersion) {
- Logger.warn(String.format("Can not find version update task from version %s to version %s", previousVersion,
- currentVersion));
- }
-
- return result;
-
- }
-
- /**
- * used to clear prepared statements.
- */
- public abstract void clearCompiledStatements();
-
- /**
- * Context.
- *
- * @return the SQL context
- */
- public SQLContext getContext() {
- return context;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see android.database.sqlite.SQLiteOpenHelper#close()
- */
- @Override
- public void close() {
- beginLock();
- try {
- if (openCounter.decrementAndGet() <= 0) {
-
- if (!this.options.inMemory) {
- // Closing database
- if (database != null) {
- clearCompiledStatements();
- sqliteHelper.close();
- }
- database = null;
- }
- if (logEnabled)
- Logger.info("database CLOSED (%s) (connections: %s)", status.get(), openCounter.intValue());
- } else {
- if (logEnabled)
- Logger.info("database RELEASED (%s) (connections: %s)", status.get(), openCounter.intValue());
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw (e);
- } finally {
- manageStatus();
- endLock();
- }
-
- }
-
- protected void closeThreadSafeMode(Pair status) {
- if (status.value0==true) {
- close();
- } else {
- beginLock();
- // we unlock lockReadWriteAccess, so we can include this code in
- // lockDb
- manageStatus();
- endLock();
-
- // unlocked inside
- // lockDb.unlock();
- }
- }
-
- /**
- * Content values.
- *
- * @param compiledStatement
- * the compiled statement
- * @return the kripton content values
- */
- protected KriptonContentValues contentValues(SupportSQLiteStatement compiledStatement) {
- return context.contentValues(compiledStatement);
- }
-
- /**
- * Content values for content provider.
- *
- * @param values
- * the values
- * @return the kripton content values
- */
- protected KriptonContentValues contentValuesForContentProvider(ContentValues values) {
- return context.contentValuesForContentProvider(values);
- }
-
- /**
- * Content values for update.
- *
- * @param compiledStatement
- * the compiled statement
- * @return the kripton content values
- */
- protected KriptonContentValues contentValuesForUpdate(SupportSQLiteStatement compiledStatement) {
- return context.contentValuesForUpdate(compiledStatement);
- }
-
- /**
- * Creates the helper.
- *
- * @param options
- * the options
- *
- */
- protected void createHelper() {
- if (KriptonLibrary.getContext() == null)
- throw new KriptonRuntimeException(
- "Kripton library is not properly initialized. Please use KriptonLibrary.init(context) somewhere at application startup");
-
- if (this.logEnabled) {
- if (options.inMemory) {
- Logger.info("In-memory database");
- } else {
- File dbFile = KriptonLibrary.getContext().getDatabasePath(name);
- Logger.info("Database file %s", dbFile.getAbsolutePath());
- }
- }
-
- Builder config = SupportSQLiteOpenHelper.Configuration.builder(KriptonLibrary.getContext()).name(name)
- .callback(new SupportSQLiteOpenHelper.Callback(version) {
-
- @Override
- public void onConfigure(SupportSQLiteDatabase db) {
- AbstractDataSource.this.onConfigure(db);
- }
-
- @Override
- public void onCorruption(SupportSQLiteDatabase db) {
- AbstractDataSource.this.onCorruption(db);
- }
-
- @Override
- public void onCreate(SupportSQLiteDatabase db) {
- sqliteHelper.setWriteAheadLoggingEnabled(true);
- AbstractDataSource.this.onCreate(db);
- }
-
- @Override
- public void onDowngrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
- AbstractDataSource.this.onDowngrade(db, oldVersion, newVersion);
- }
-
- @Override
- public void onOpen(SupportSQLiteDatabase db) {
- sqliteHelper.setWriteAheadLoggingEnabled(true);
- AbstractDataSource.this.onOpen(db);
- }
-
- @Override
- public void onUpgrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
- AbstractDataSource.this.onUpgrade(db, oldVersion, newVersion);
- }
- });
-
- sqliteHelper = options.openHelperFactory.create(config.build());
-
- if (this.logEnabled) {
- Logger.debug("Database helper factory class is %s", options.openHelperFactory.getClass().getName());
- Logger.debug("Database helper class is %s", sqliteHelper.getClass().getName());
- }
- }
-
- private void deleteDatabaseFile(String fileName) {
- if (fileName.equalsIgnoreCase(":memory:") || fileName.trim().length() == 0) {
- return;
- }
- if (this.logEnabled) {
- Logger.fatal("deleting the database file: " + fileName);
- }
- try {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- SQLiteDatabase.deleteDatabase(new File(fileName));
- } else {
- try {
- final boolean deleted = new File(fileName).delete();
- if (!deleted) {
- if (this.logEnabled) {
- Logger.fatal("Could not delete the database file " + fileName);
- }
- }
- } catch (Exception error) {
- if (this.logEnabled) {
- Logger.fatal("error while deleting corrupted database file " + error.getMessage());
- }
- }
- }
- } catch (Exception e) {
- if (this.logEnabled) {
- /* print warning and ignore exception */
- Logger.warn("delete failed: ", e);
- }
- }
- }
-
- protected void endLock() {
- lockDb.unlock();
- }
-
- /**
- * Force close.
- */
- void forceClose() {
- openCounter.set(0);
- }
-
- /**
- *
- * Return database object or runtimeexception if no database is opened.
- *
- *
- * @return the SQ lite database
- */
- public SupportSQLiteDatabase getDatabase() {
- if (database == null)
- throw (new KriptonRuntimeException(
- "No database connection is opened before use " + this.getClass().getCanonicalName()));
- return database;
- }
-
- public String getName() {
- return name;
- }
-
- // /**
- // * Sets the version.
- // *
- // * @param version
- // * the new version
- // */
- // public void setVersion(int version) {
- // this.version = version;
- // }
-
- /**
- * Get error listener, in transations.
- *
- * @return the on error listener
- */
- public OnErrorListener getOnErrorListener() {
- return onErrorListener;
- }
-
- /**
- * Gets the version.
- *
- * @return the version
- */
- public int getVersion() {
- return version;
- }
-
- /**
- *
- * True if dataSource is just created
- *
- * .
- *
- * @return true, if is just created
- */
- public boolean isJustCreated() {
- return justCreated;
- }
-
- /**
- * Checks if is log enabled.
- *
- * @return true, if is log enabled
- */
- public boolean isLogEnabled() {
- return context.isLogEnabled();
- }
-
- /**
- *
- * return true if database is already opened.
- *
- *
- * @return true if database is opened, otherwise false
- */
- public boolean isOpen() {
- return database != null && database.isOpen() && database.isDbLockedByCurrentThread();
- }
-
- /**
- * Return true
if any operation is running on datasource,
- * false
if database is currently closed.
- *
- * @return
- */
- public boolean isAnyPendingOperation() {
- return openCounter.get() > 0;
- }
-
- /**
- *
- * return true if database is already opened in write mode.
- *
- *
- * @return true if database is opened, otherwise false
- */
- public boolean isOpenInWriteMode() {
- // return database != null && database.isOpen() &&
- // !database.isReadOnly() && database.isDbLockedByCurrentThread();
- return database != null && database.isOpen() && !database.isReadOnly() && database.isDbLockedByCurrentThread();
- }
-
- /**
- * Checks if is upgraded version.
- *
- * @return the upgradedVersion
- */
- public boolean isUpgradedVersion() {
- return versionChanged;
- }
-
- /**
- *
- */
- private void manageStatus() {
- switch (status.get()) {
- case READ_AND_WRITE_OPENED:
- if (database == null)
- status.set(TypeStatus.CLOSED);
- lockReadWriteAccess.unlock();
- // lockDb.unlock();
- break;
- case READ_ONLY_OPENED:
- if (database == null)
- status.set(TypeStatus.CLOSED);
- lockReadAccess.unlock();
- // lockDb.unlock();
- break;
- case CLOSED:
- // do nothing
- // lockDb.unlock();
- break;
- }
- }
-
- /**
- * Returns true
if the database need foreign keys
- *
- * @return
- *
- */
- public abstract boolean hasForeignKeys();
-
- /**
- * On configure.
- *
- * @param database
- * the database
- */
- protected void onConfigure(SupportSQLiteDatabase database) {
- // configure database
- // database.setForeignKeyConstraintsEnabled(true);
- if (options.databaseLifecycleHandler != null) {
- options.databaseLifecycleHandler.onConfigure(database);
- }
- }
- // protected abstract void onConfigure(SupportSQLiteDatabase database);
-
- /**
- * The method invoked when database corruption is detected. Default
- * implementation will delete the database file.
- *
- * @param db
- * the {@link SupportSQLiteDatabase} object representing the
- * database on which corruption is detected.
- */
- protected void onCorruption(@NonNull SupportSQLiteDatabase db) {
- // the following implementation is taken from {@link
- // DefaultDatabaseErrorHandler}.
- if (this.logEnabled) {
- Logger.fatal("Corruption reported by sqlite on database: " + db.getPath());
- }
- try {
- if (options.databaseLifecycleHandler != null) {
- options.databaseLifecycleHandler.onCorruption(db);
- }
- } catch (Throwable e) {
- e.printStackTrace();
- }
-
- // is the corruption detected even before database could be 'opened'?
- if (!db.isOpen()) {
- // database files are not even openable. delete this database file.
- // NOTE if the database has attached databases, then any of them
- // could be corrupt.
- // and not deleting all of them could cause corrupted database file
- // to remain and
- // make the application crash on database open operation. To avoid
- // this problem,
- // the application should provide its own {@link
- // DatabaseErrorHandler} impl class
- // to delete ALL files of the database (including the attached
- // databases).
- deleteDatabaseFile(db.getPath());
- return;
- }
- List> attachedDbs = null;
- try {
- // Close the database, which will cause subsequent operations to
- // fail.
- // before that, get the attached database list first.
- try {
- attachedDbs = db.getAttachedDbs();
- } catch (SQLiteException e) {
- /* ignore */
- }
- try {
- db.close();
- } catch (IOException e) {
- /* ignore */
- }
- } finally {
- // Delete all files of this corrupt database and/or attached
- // databases
- if (attachedDbs != null) {
- for (android.util.Pair p : attachedDbs) {
- deleteDatabaseFile(p.second);
- }
- } else {
- // attachedDbs = null is possible when the database is so
- // corrupt that even
- // "PRAGMA database_list;" also fails. delete the main database
- // file
- deleteDatabaseFile(db.getPath());
- }
- }
- }
-
- /**
- * On create.
- *
- * @param database
- * the database
- */
- protected abstract void onCreate(SupportSQLiteDatabase database);
-
- /**
- * On downgrade.
- *
- * @param db
- * the db
- * @param oldVersion
- * the old version
- * @param newVersion
- * the new version
- */
- protected void onDowngrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
- if (options.databaseLifecycleHandler != null) {
- options.databaseLifecycleHandler.onUpdate(db, oldVersion, newVersion, false);
- versionChanged = true;
- }
- }
-
- protected void onOpen(SupportSQLiteDatabase db) {
- if (AbstractDataSource.this.options.databaseLifecycleHandler != null) {
- AbstractDataSource.this.options.databaseLifecycleHandler.onOpen(db);
- versionChanged = true;
- }
- }
-
- /**
- * On session closed.
- *
- * @return the sets the
- */
- protected Set onSessionClosed() {
- return this.context.onSessionClosed();
-
- }
-
- /**
- * On session opened.
- */
- protected void onSessionOpened() {
- this.context.onSessionOpened();
- }
-
- /**
- * On upgrade.
- *
- * @param db
- * the db
- * @param oldVersion
- * the old version
- * @param newVersion
- * the new version
- */
- protected void onUpgrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
- if (AbstractDataSource.this.options.databaseLifecycleHandler != null) {
- AbstractDataSource.this.options.databaseLifecycleHandler.onUpdate(db, oldVersion, newVersion, true);
- versionChanged = true;
- }
- }
-
- /**
- * Open a database, if it is needed in
- *
- * @param writeMode
- * @return
- */
- protected Pair openDatabaseThreadSafeMode(boolean writeMode) {
- Pair result = new Pair();
-
- try {
- // lock entire operation set
- beginLock();
- boolean needToOpened = writeMode ? !this.isOpenInWriteMode() : !this.isOpen();
- result.value0 = needToOpened;
- // in this part we can not lock lockReadWriteAccess, otherwise it
- // may be a
- // blocking race
- // we lock lockReadWriteAccess after we release
- if (needToOpened) {
- if (writeMode) {
- result.value1 = openWritableDatabase(false);
- } else {
- result.value1 = openReadOnlyDatabase(false);
- }
- } else {
- result.value1 = this.getDatabase();
- }
-
- } finally {
- // unlock entire operation set
- endLock();
-
- if (writeMode) {
- lockReadWriteAccess.lock();
- } else {
- lockReadAccess.lock();
- }
-
- }
-
- return result;
-
- }
-
- public SupportSQLiteDatabase openReadOnlyDatabase() {
- return openReadOnlyDatabase(true);
- }
-
- /**
- *
- * Open a read only database.
- *
- *
- * @return read only database
- */
- protected SupportSQLiteDatabase openReadOnlyDatabase(boolean lock) {
- if (lock) {
- // if I lock this in dbLock.. the last one remains locked too
- lockReadAccess.lock();
-
- beginLock();
- }
-
- try {
- if (sqliteHelper == null)
- createHelper();
-
- status.set(TypeStatus.READ_ONLY_OPENED);
-
- if (openCounter.incrementAndGet() == 1) {
- // open new read database
- if (database == null) {
- sqliteHelper.setWriteAheadLoggingEnabled(true);
- database = sqliteHelper.getReadableDatabase();
- database.setForeignKeyConstraintsEnabled(hasForeignKeys());
- }
- if (logEnabled)
- Logger.info("database OPEN %s (connections: %s)", status.get(), (openCounter.intValue() - 1));
- } else {
- if (logEnabled)
- Logger.info("database REUSE %s (connections: %s)", status.get(), (openCounter.intValue() - 1));
- }
- } catch (Throwable e) {
- if (logEnabled) {
- Logger.fatal("database error during open operation: %s", e.getMessage());
- e.printStackTrace();
- }
- throw (e);
- } finally {
- if (lock)
- endLock();
-
- }
-
- return database;
- }
-
- /**
- *
- * open a writable database.
- *
- *
- * @return writable database
- */
- public SupportSQLiteDatabase openWritableDatabase() {
- return openWritableDatabase(true);
- }
-
- protected SupportSQLiteDatabase openWritableDatabase(boolean lock) {
- if (lock) {
- lockReadWriteAccess.lock();
-
- // if I lock this in dbLock.. the last one remains locked too
- beginLock();
- }
-
- try {
- if (sqliteHelper == null)
- createHelper();
-
- status.set(TypeStatus.READ_AND_WRITE_OPENED);
-
- if (openCounter.incrementAndGet() == 1) {
- // open new write database
- if (database == null) {
- sqliteHelper.setWriteAheadLoggingEnabled(true);
- database = sqliteHelper.getWritableDatabase();
- database.setForeignKeyConstraintsEnabled(hasForeignKeys());
- }
- if (logEnabled)
- Logger.info("database OPEN %s (connections: %s)", status.get(), (openCounter.intValue() - 1));
- } else {
- if (logEnabled)
- Logger.info("database REUSE %s (connections: %s)", status.get(), (openCounter.intValue() - 1));
- }
- } catch (Throwable e) {
- if (logEnabled) {
- Logger.fatal("database error during open operation: %s", e.getMessage());
- e.printStackTrace();
- }
- throw (e);
- } finally {
- if (lock)
- endLock();
- }
-
- return database;
- }
-
- /**
- * Set error listener for transactions.
- *
- * @param onErrorListener
- * the new on error listener
- */
- public void setOnErrorListener(OnErrorListener onErrorListener) {
- this.onErrorListener = onErrorListener;
- }
-
- /**
- * Sql builder.
- *
- * @return the string builder
- */
- protected StringBuilder sqlBuilder() {
- return context.sqlBuilder();
- }
+ /**
+ * Interface for database operations.
+ *
+ * @param
+ * the element type
+ */
+ public interface AbstractExecutable {
+
+ /**
+ * Execute transation. Method need to return
+ * {@link TransactionResult#COMMIT} to commit results or
+ * {@link TransactionResult#ROLLBACK} to rollback. If exception is
+ * thrown, a rollback will be done.
+ *
+ * @param daoFactory
+ * the dao factory
+ * @return the transaction result
+ */
+ TransactionResult onExecute(E daoFactory);
+ }
+
+ /**
+ * The listener interface for receiving onError events. The class that is
+ * interested in processing a onError event implements this interface, and
+ * the object created with that class is registered with a component using
+ * the component's addOnErrorListener
method. When the onError
+ * event occurs, that object's appropriate method is invoked.
+ *
+ */
+ public interface OnErrorListener {
+ /**
+ * Manages error situations.
+ *
+ * @param e
+ * exception
+ */
+ void onError(Throwable e);
+ }
+
+ /**
+ * The Enum TypeStatus.
+ */
+ public enum TypeStatus {
+
+ /** The closed. */
+ CLOSED,
+ /** The read and write opened. */
+ READ_AND_WRITE_OPENED,
+ /** The read only opened. */
+ READ_ONLY_OPENED
+ }
+
+ /** The context. */
+ protected SQLContextImpl context;
+
+ /** database instance. */
+ SupportSQLiteDatabase database;
+
+ /**
+ *
+ * True if dataSource is just created
+ *
+ * .
+ */
+ protected boolean justCreated = false;
+
+ /** The lock access. */
+ private final ReentrantReadWriteLock lockAccess = new ReentrantReadWriteLock();
+
+ /** The lock db. */
+ private final ReentrantLock lockDb = new ReentrantLock();
+
+ /** The lock read access. */
+ private final Lock lockReadAccess = lockAccess.readLock();
+
+ /** The lock read write access. */
+ private final Lock lockReadWriteAccess = lockAccess.writeLock();
+
+ /** The log enabled. */
+ protected boolean logEnabled;
+
+ /**
+ *
+ * file name used to save database,
+ *
+ * .
+ */
+ protected final String name;
+
+ /** The on error listener. */
+ protected OnErrorListener onErrorListener = (Throwable e) -> {
+ throw (new KriptonRuntimeException(e));
+ };
+
+
+ /** The open counter. */
+ private final AtomicInteger openCounter = new AtomicInteger();
+
+ /** The options. */
+ protected DataSourceOptions options;
+
+ /** The sqlite helper. */
+ protected SupportSQLiteOpenHelper sqliteHelper;
+
+ /** The status. */
+ protected ThreadLocal status = ThreadLocal.withInitial(() -> TypeStatus.CLOSED);
+
+ /**
+ *
+ * database version
+ *
+ * .
+ */
+ protected int version;
+
+ /** if true, database was update during this application run. */
+ protected boolean versionChanged;
+
+ /**
+ * Instantiates a new abstract data source.
+ *
+ * @param name
+ * the name
+ * @param version
+ * the version
+ * @param options
+ * the options
+ */
+ protected AbstractDataSource(String name, int version, DataSourceOptions options) {
+ DataSourceOptions optionsValue = (options != null) ? options : DataSourceOptions.builder().build();
+
+ this.name = optionsValue.inMemory ? null : name;
+ this.version = version;
+
+ // create new SQLContext
+ this.context = new SQLContextImpl(this);
+
+ this.options = optionsValue;
+ this.logEnabled = optionsValue.logEnabled;
+
+ if (this.logEnabled) {
+ Logger.debug("%s is created with %s", getClass().getName(), optionsValue.toString());
+ }
+ }
+
+ protected void beginLock() {
+ lockDb.lock();
+ }
+
+ /**
+ * Builds the task list.
+ *
+ * @param previousVersion
+ * the previous version
+ * @param currentVersion
+ * the current version
+ * @return the list
+ */
+ protected List buildTaskList(int previousVersion, int currentVersion) {
+ List result = new ArrayList<>();
+
+ for (Pair item : this.options.updateTasks) {
+ if (item.value0 - 1 == previousVersion) {
+ result.add(item.value1);
+ previousVersion = item.value0;
+ }
+
+ if (previousVersion == currentVersion)
+ break;
+ }
+
+ if (previousVersion != currentVersion) {
+ Logger.warn(String.format("Can not find version update task from version %s to version %s", previousVersion,
+ currentVersion));
+ }
+
+ return result;
+
+ }
+
+ /**
+ * used to clear prepared statements.
+ */
+ public abstract void clearCompiledStatements();
+
+ /**
+ * Context.
+ *
+ * @return the SQL context
+ */
+ public SQLContext getContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see android.database.sqlite.SQLiteOpenHelper#close()
+ */
+ @Override
+ public void close() {
+ beginLock();
+ try {
+ if (openCounter.decrementAndGet() <= 0) {
+
+ if (!this.options.inMemory) {
+ // Closing database
+ if (database != null) {
+ clearCompiledStatements();
+ sqliteHelper.close();
+ }
+ database = null;
+ }
+ if (logEnabled)
+ Logger.info("database CLOSED (%s) (connections: %s)", status.get(), openCounter.intValue());
+ } else {
+ if (logEnabled)
+ Logger.info("database RELEASED (%s) (connections: %s)", status.get(), openCounter.intValue());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw (e);
+ } finally {
+ manageStatus();
+ endLock();
+ }
+
+ }
+
+ protected void closeThreadSafeMode(Pair status) {
+ if (status.value0 == true) {
+ close();
+ } else {
+ beginLock();
+ // we unlock lockReadWriteAccess, so we can include this code in
+ // lockDb
+ manageStatus();
+ endLock();
+
+ // unlocked inside
+ // lockDb.unlock();
+ }
+ }
+
+ /**
+ * Content values.
+ *
+ * @param compiledStatement
+ * the compiled statement
+ * @return the kripton content values
+ */
+ protected KriptonContentValues contentValues(SupportSQLiteStatement compiledStatement) {
+ return context.contentValues(compiledStatement);
+ }
+
+ /**
+ * Content values for content provider.
+ *
+ * @param values
+ * the values
+ * @return the kripton content values
+ */
+ protected KriptonContentValues contentValuesForContentProvider(ContentValues values) {
+ return context.contentValuesForContentProvider(values);
+ }
+
+ /**
+ * Content values for update.
+ *
+ * @param compiledStatement
+ * the compiled statement
+ * @return the kripton content values
+ */
+ protected KriptonContentValues contentValuesForUpdate(SupportSQLiteStatement compiledStatement) {
+ return context.contentValuesForUpdate(compiledStatement);
+ }
+
+ /**
+ * Creates the helper.
+ */
+ protected void createHelper() {
+ if (KriptonLibrary.getContext() == null)
+ throw new KriptonRuntimeException(
+ "Kripton library is not properly initialized. Please use KriptonLibrary.init(context) somewhere at application startup");
+
+ if (this.logEnabled) {
+ if (options.inMemory) {
+ Logger.info("In-memory database");
+ } else {
+ File dbFile = KriptonLibrary.getContext().getDatabasePath(name);
+ Logger.info("Database file %s", dbFile.getAbsolutePath());
+ }
+ }
+
+ Builder config = SupportSQLiteOpenHelper.Configuration.builder(KriptonLibrary.getContext()).name(name)
+ .callback(new SupportSQLiteOpenHelper.Callback(version) {
+
+ @Override
+ public void onConfigure(SupportSQLiteDatabase db) {
+ AbstractDataSource.this.onConfigure(db);
+ }
+
+ @Override
+ public void onCorruption(SupportSQLiteDatabase db) {
+ AbstractDataSource.this.onCorruption(db);
+ }
+
+ @Override
+ public void onCreate(SupportSQLiteDatabase db) {
+ sqliteHelper.setWriteAheadLoggingEnabled(true);
+ AbstractDataSource.this.onCreate(db);
+ }
+
+ @Override
+ public void onDowngrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
+ AbstractDataSource.this.onDowngrade(db, oldVersion, newVersion);
+ }
+
+ @Override
+ public void onOpen(SupportSQLiteDatabase db) {
+ sqliteHelper.setWriteAheadLoggingEnabled(true);
+ AbstractDataSource.this.onOpen(db);
+ }
+
+ @Override
+ public void onUpgrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
+ AbstractDataSource.this.onUpgrade(db, oldVersion, newVersion);
+ }
+ });
+
+ sqliteHelper = options.openHelperFactory.create(config.build());
+
+ if (this.logEnabled) {
+ Logger.debug("Database helper factory class is %s", options.openHelperFactory.getClass().getName());
+ Logger.debug("Database helper class is %s", sqliteHelper.getClass().getName());
+ }
+ }
+
+ private void deleteDatabaseFile(String fileName) {
+ if (fileName.equalsIgnoreCase(":memory:") || fileName.trim().length() == 0) {
+ return;
+ }
+ if (this.logEnabled) {
+ Logger.fatal("deleting the database file: " + fileName);
+ }
+ try {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ SQLiteDatabase.deleteDatabase(new File(fileName));
+ } else {
+ try {
+ final boolean deleted = new File(fileName).delete();
+ if (!deleted) {
+ if (this.logEnabled) {
+ Logger.fatal("Could not delete the database file " + fileName);
+ }
+ }
+ } catch (Exception error) {
+ if (this.logEnabled) {
+ Logger.fatal("error while deleting corrupted database file " + error.getMessage());
+ }
+ }
+ }
+ } catch (Exception e) {
+ if (this.logEnabled) {
+ /* print warning and ignore exception */
+ Logger.warn("delete failed: ", e);
+ }
+ }
+ }
+
+ protected void endLock() {
+ lockDb.unlock();
+ }
+
+ /**
+ * Force close.
+ */
+ void forceClose() {
+ openCounter.set(0);
+ }
+
+ /**
+ *
+ * Return database object or runtimeexception if no database is opened.
+ *
+ *
+ * @return the SQ lite database
+ */
+ public SupportSQLiteDatabase getDatabase() {
+ if (database == null)
+ throw (new KriptonRuntimeException(
+ "No database connection is opened before use " + this.getClass().getCanonicalName()));
+ return database;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ // /**
+ // * Sets the version.
+ // *
+ // * @param version
+ // * the new version
+ // */
+ // public void setVersion(int version) {
+ // this.version = version;
+ // }
+
+ /**
+ * Get error listener, in transations.
+ *
+ * @return the on error listener
+ */
+ public OnErrorListener getOnErrorListener() {
+ return onErrorListener;
+ }
+
+ /**
+ * Gets the version.
+ *
+ * @return the version
+ */
+ public int getVersion() {
+ return version;
+ }
+
+ /**
+ *
+ * True if dataSource is just created
+ *
+ * .
+ *
+ * @return true, if is just created
+ */
+ public boolean isJustCreated() {
+ return justCreated;
+ }
+
+ /**
+ * Checks if is log enabled.
+ *
+ * @return true, if is log enabled
+ */
+ public boolean isLogEnabled() {
+ return context.isLogEnabled();
+ }
+
+ /**
+ *
+ * return true if database is already opened.
+ *
+ *
+ * @return true if database is opened, otherwise false
+ */
+ public boolean isOpen() {
+ return database != null && database.isOpen() && database.isDbLockedByCurrentThread();
+ }
+
+ /**
+ * Return true
if any operation is running on datasource,
+ * false
if database is currently closed.
+ *
+ * @return
+ */
+ public boolean isAnyPendingOperation() {
+ return openCounter.get() > 0;
+ }
+
+ /**
+ *
+ * return true if database is already opened in write mode.
+ *
+ *
+ * @return true if database is opened, otherwise false
+ */
+ public boolean isOpenInWriteMode() {
+ // return database != null && database.isOpen() &&
+ // !database.isReadOnly() && database.isDbLockedByCurrentThread();
+ return database != null && database.isOpen() && !database.isReadOnly() && database.isDbLockedByCurrentThread();
+ }
+
+ /**
+ * Checks if is upgraded version.
+ *
+ * @return the upgradedVersion
+ */
+ public boolean isUpgradedVersion() {
+ return versionChanged;
+ }
+
+ /**
+ *
+ */
+ private void manageStatus() {
+ switch (status.get()) {
+ case READ_AND_WRITE_OPENED:
+ if (database == null)
+ status.set(TypeStatus.CLOSED);
+ lockReadWriteAccess.unlock();
+ // lockDb.unlock();
+ break;
+ case READ_ONLY_OPENED:
+ if (database == null)
+ status.set(TypeStatus.CLOSED);
+ lockReadAccess.unlock();
+ // lockDb.unlock();
+ break;
+ case CLOSED:
+ // do nothing
+ // lockDb.unlock();
+ break;
+ }
+ }
+
+ /**
+ * Returns true
if the database need foreign keys
+ *
+ * @return
+ *
+ */
+ public abstract boolean hasForeignKeys();
+
+ /**
+ * On configure.
+ *
+ * @param database
+ * the database
+ */
+ protected void onConfigure(SupportSQLiteDatabase database) {
+ // configure database
+ // database.setForeignKeyConstraintsEnabled(true);
+ if (options.databaseLifecycleHandler != null) {
+ options.databaseLifecycleHandler.onConfigure(database);
+ }
+ }
+ // protected abstract void onConfigure(SupportSQLiteDatabase database);
+
+ /**
+ * The method invoked when database corruption is detected. Default
+ * implementation will delete the database file.
+ *
+ * @param db
+ * the {@link SupportSQLiteDatabase} object representing the
+ * database on which corruption is detected.
+ */
+ protected void onCorruption(@NonNull SupportSQLiteDatabase db) {
+ // the following implementation is taken from {@link
+ // DefaultDatabaseErrorHandler}.
+ if (this.logEnabled) {
+ Logger.fatal("Corruption reported by sqlite on database: " + db.getPath());
+ }
+ try {
+ if (options.databaseLifecycleHandler != null) {
+ options.databaseLifecycleHandler.onCorruption(db);
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+
+ // is the corruption detected even before database could be 'opened'?
+ if (!db.isOpen()) {
+ // database files are not even openable. delete this database file.
+ // NOTE if the database has attached databases, then any of them
+ // could be corrupt.
+ // and not deleting all of them could cause corrupted database file
+ // to remain and
+ // make the application crash on database open operation. To avoid
+ // this problem,
+ // the application should provide its own {@link
+ // DatabaseErrorHandler} impl class
+ // to delete ALL files of the database (including the attached
+ // databases).
+ deleteDatabaseFile(db.getPath());
+ return;
+ }
+ List> attachedDbs = null;
+ try {
+ // Close the database, which will cause subsequent operations to
+ // fail.
+ // before that, get the attached database list first.
+ try {
+ attachedDbs = db.getAttachedDbs();
+ } catch (SQLiteException e) {
+ /* ignore */
+ }
+ try {
+ db.close();
+ } catch (IOException e) {
+ /* ignore */
+ }
+ } finally {
+ // Delete all files of this corrupt database and/or attached
+ // databases
+ if (attachedDbs != null) {
+ for (android.util.Pair p : attachedDbs) {
+ deleteDatabaseFile(p.second);
+ }
+ } else {
+ // attachedDbs = null is possible when the database is so
+ // corrupt that even
+ // "PRAGMA database_list;" also fails. delete the main database
+ // file
+ deleteDatabaseFile(db.getPath());
+ }
+ }
+ }
+
+ /**
+ * On create.
+ *
+ * @param database
+ * the database
+ */
+ protected abstract void onCreate(SupportSQLiteDatabase database);
+
+ /**
+ * On downgrade.
+ *
+ * @param db
+ * the db
+ * @param oldVersion
+ * the old version
+ * @param newVersion
+ * the new version
+ */
+ protected void onDowngrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
+ if (options.databaseLifecycleHandler != null) {
+ options.databaseLifecycleHandler.onUpdate(db, oldVersion, newVersion, false);
+ versionChanged = true;
+ }
+ }
+
+ protected void onOpen(SupportSQLiteDatabase db) {
+ if (AbstractDataSource.this.options.databaseLifecycleHandler != null) {
+ AbstractDataSource.this.options.databaseLifecycleHandler.onOpen(db);
+ versionChanged = true;
+ }
+ }
+
+ /**
+ * On session closed.
+ *
+ * @return the sets the
+ */
+ protected Set onSessionClosed() {
+ return this.context.onSessionClosed();
+
+ }
+
+ /**
+ * On session opened.
+ */
+ protected void onSessionOpened() {
+ this.context.onSessionOpened();
+ }
+
+ /**
+ * On upgrade.
+ *
+ * @param db
+ * the db
+ * @param oldVersion
+ * the old version
+ * @param newVersion
+ * the new version
+ */
+ protected void onUpgrade(SupportSQLiteDatabase db, int oldVersion, int newVersion) {
+ if (AbstractDataSource.this.options.databaseLifecycleHandler != null) {
+ AbstractDataSource.this.options.databaseLifecycleHandler.onUpdate(db, oldVersion, newVersion, true);
+ versionChanged = true;
+ }
+ }
+
+ /**
+ * Open a database, if it is needed in
+ *
+ * @param writeMode
+ * @return
+ */
+ protected Pair openDatabaseThreadSafeMode(boolean writeMode) {
+ Pair result = new Pair();
+
+ try {
+ // lock entire operation set
+ beginLock();
+ boolean needToOpened = writeMode ? !this.isOpenInWriteMode() : !this.isOpen();
+ result.value0 = needToOpened;
+ // in this part we can not lock lockReadWriteAccess, otherwise it
+ // may be a
+ // blocking race
+ // we lock lockReadWriteAccess after we release
+ if (needToOpened) {
+ if (writeMode) {
+ result.value1 = openWritableDatabase(false);
+ } else {
+ result.value1 = openReadOnlyDatabase(false);
+ }
+ } else {
+ result.value1 = this.getDatabase();
+ }
+
+ } finally {
+ // unlock entire operation set
+ endLock();
+
+ if (writeMode) {
+ lockReadWriteAccess.lock();
+ } else {
+ lockReadAccess.lock();
+ }
+
+ }
+
+ return result;
+
+ }
+
+ public SupportSQLiteDatabase openReadOnlyDatabase() {
+ return openReadOnlyDatabase(true);
+ }
+
+ /**
+ *
+ * Open a read only database.
+ *
+ *
+ * @return read only database
+ */
+ protected SupportSQLiteDatabase openReadOnlyDatabase(boolean lock) {
+ if (lock) {
+ // if I lock this in dbLock.. the last one remains locked too
+ lockReadAccess.lock();
+
+ beginLock();
+ }
+
+ try {
+ if (sqliteHelper == null)
+ createHelper();
+
+ status.set(TypeStatus.READ_ONLY_OPENED);
+
+ if (openCounter.incrementAndGet() == 1) {
+ // open new read database
+ if (database == null) {
+ sqliteHelper.setWriteAheadLoggingEnabled(true);
+ database = sqliteHelper.getReadableDatabase();
+ database.setForeignKeyConstraintsEnabled(hasForeignKeys());
+ }
+ if (logEnabled)
+ Logger.info("database OPEN %s (connections: %s)", status.get(), (openCounter.intValue() - 1));
+ } else {
+ if (logEnabled)
+ Logger.info("database REUSE %s (connections: %s)", status.get(), (openCounter.intValue() - 1));
+ }
+ } catch (Throwable e) {
+ if (logEnabled) {
+ Logger.fatal("database error during open operation: %s", e.getMessage());
+ e.printStackTrace();
+ }
+ throw (e);
+ } finally {
+ if (lock)
+ endLock();
+
+ }
+
+ return database;
+ }
+
+ /**
+ *
+ * open a writable database.
+ *
+ *
+ * @return writable database
+ */
+ public SupportSQLiteDatabase openWritableDatabase() {
+ return openWritableDatabase(true);
+ }
+
+ protected SupportSQLiteDatabase openWritableDatabase(boolean lock) {
+ if (lock) {
+ lockReadWriteAccess.lock();
+
+ // if I lock this in dbLock.. the last one remains locked too
+ beginLock();
+ }
+
+ try {
+ if (sqliteHelper == null)
+ createHelper();
+
+ status.set(TypeStatus.READ_AND_WRITE_OPENED);
+
+ if (openCounter.incrementAndGet() == 1) {
+ // open new write database
+ if (database == null) {
+ sqliteHelper.setWriteAheadLoggingEnabled(true);
+ database = sqliteHelper.getWritableDatabase();
+ database.setForeignKeyConstraintsEnabled(hasForeignKeys());
+ }
+ if (logEnabled)
+ Logger.info("database OPEN %s (connections: %s)", status.get(), (openCounter.intValue() - 1));
+ } else {
+ if (logEnabled)
+ Logger.info("database REUSE %s (connections: %s)", status.get(), (openCounter.intValue() - 1));
+ }
+ } catch (Throwable e) {
+ if (logEnabled) {
+ Logger.fatal("database error during open operation: %s", e.getMessage());
+ e.printStackTrace();
+ }
+ throw (e);
+ } finally {
+ if (lock)
+ endLock();
+ }
+
+ return database;
+ }
+
+ /**
+ * Set error listener for transactions.
+ *
+ * @param onErrorListener
+ * the new on error listener
+ */
+ public void setOnErrorListener(OnErrorListener onErrorListener) {
+ this.onErrorListener = onErrorListener;
+ }
+
+ /**
+ * Sql builder.
+ *
+ * @return the string builder
+ */
+ protected StringBuilder sqlBuilder() {
+ return context.sqlBuilder();
+ }
}
diff --git a/kripton-parent/pom.xml b/kripton-parent/pom.xml
index 55ded1358..1bd76be23 100644
--- a/kripton-parent/pom.xml
+++ b/kripton-parent/pom.xml
@@ -12,7 +12,7 @@
com.abubusoft
kripton-parent
- 7.0.0-rc.8
+ 7.0.0-rc.9
pom
Kripton (Parent)
@@ -38,7 +38,7 @@
3.2.0
3.0.1
- 7.0.0-rc.8
+ 7.0.0-rc.9
2.11.2
@@ -51,7 +51,7 @@
3.0.1
3.1.4
- 7.0.0-rc.8_r1-robolectric-0
+ 7.0.0-rc.9_r1-robolectric-0
1.9.0
diff --git a/kripton-processor/pom.xml b/kripton-processor/pom.xml
index 2dd07a37d..5ed7d6f54 100644
--- a/kripton-processor/pom.xml
+++ b/kripton-processor/pom.xml
@@ -14,7 +14,7 @@
com.abubusoft
kripton-parent
- 7.0.0-rc.8
+ 7.0.0-rc.9
../kripton-parent/pom.xml
@@ -26,7 +26,7 @@
false
- 7.0.0-rc.8
+ 7.0.0-rc.9
2.11.2
diff --git a/kripton-retrofit-converter/pom.xml b/kripton-retrofit-converter/pom.xml
index db19f4f0a..c8e731f90 100644
--- a/kripton-retrofit-converter/pom.xml
+++ b/kripton-retrofit-converter/pom.xml
@@ -5,7 +5,7 @@
com.abubusoft
kripton-parent
- 7.0.0-rc.8
+ 7.0.0-rc.9
../kripton-parent/pom.xml
@@ -16,7 +16,7 @@
1.8
- 7.0.0-rc.8
+ 7.0.0-rc.9
2.11.2
diff --git a/kripton-shared-preferences/kripton-shared-preferences.iml b/kripton-shared-preferences/kripton-shared-preferences.iml
index be2e2d436..dbf25cacc 100644
--- a/kripton-shared-preferences/kripton-shared-preferences.iml
+++ b/kripton-shared-preferences/kripton-shared-preferences.iml
@@ -69,7 +69,7 @@
-
+
diff --git a/kripton-shared-preferences/pom.xml b/kripton-shared-preferences/pom.xml
index 0f2d6c752..57482ad7a 100644
--- a/kripton-shared-preferences/pom.xml
+++ b/kripton-shared-preferences/pom.xml
@@ -5,7 +5,7 @@
com.abubusoft
kripton-parent
- 7.0.0-rc.8
+ 7.0.0-rc.9
../kripton-parent/pom.xml
@@ -16,7 +16,7 @@
jar
- 7.0.0-rc.8
+ 7.0.0-rc.9
2.11.2
diff --git a/kripton-sqlite-test-library/pom.xml b/kripton-sqlite-test-library/pom.xml
index 7f4496d78..914d0bbd9 100644
--- a/kripton-sqlite-test-library/pom.xml
+++ b/kripton-sqlite-test-library/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.abubusoft
kripton-sqlite-test-library
- 7.0.0-rc.8
+ 7.0.0-rc.9
Kripton SQLite Test Library
Kripton SQLite Test Library
@@ -12,7 +12,7 @@
- 7.0.0-rc.8
+ 7.0.0-rc.9
1.8
diff --git a/kripton/pom.xml b/kripton/pom.xml
index 750c051ab..274e34e72 100644
--- a/kripton/pom.xml
+++ b/kripton/pom.xml
@@ -14,7 +14,7 @@
com.abubusoft
kripton-parent
- 7.0.0-rc.8
+ 7.0.0-rc.9
../kripton-parent/pom.xml
@@ -25,7 +25,7 @@
Kripton Persistence Library
- 7.0.0-rc.8
+ 7.0.0-rc.9
2.11.2
diff --git a/pom.xml b/pom.xml
index cec2041b9..4356698f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.abubusoft
kripton-parent
- 7.0.0-rc.8
+ 7.0.0-rc.9
./kripton-parent/pom.xml