All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.beigesoft.andr.RdbMdb Maven / Gradle / Ivy

Go to download

Beigesoft™ Enterprise Information System is a standalone JEE web application that runs on the embedded A-Jetty for Android. Web-Store is included for study and tests purposes, and you are also able to make a full DB copy from a cloud version, and you can make price lists (in different price categories) and export them via CSV files to your customers and POS.

The newest version!
/*
BSD 2-Clause License

Copyright (c) 2019, Beigesoft™
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.beigesoft.andr;

import java.util.Locale;

import android.database.Cursor;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import org.beigesoft.exc.ExcCode;
import org.beigesoft.mdl.IHasId;
import org.beigesoft.mdl.IRecSet;
import org.beigesoft.mdl.ColVals;

/**
 * 

Multi-thread implementation of database service for Android. Each thread * uses its own SQLite database instance (connection-like WITHOUT closing!!!). * Otherwise (sharing the same database reference/instance) it will leads to * problems (database locking...). Only SQLiteOpenHelper should be used for * getting database because of it must be invoked [open-helper].close() * when application is shut down/reinitialized. * SQLLite makes autocommit itself: when "TRANSACTION START", then * autocommit is off, when "END/COMMIT TRANSACTION", then autocommit is on. * Here flag autocommit (per thread) is used for high level logic, * e.g. "rollback transaction (AUTC=OFF) or not (AUTC=ON)".

* * @author Yury Demidenko */ public class RdbMdb extends ARdba { /** *

SQLiteOpenHelper one for all threads.

**/ private SQLiteOpenHelper sqliteOh; /** *

Auto-commit flag per thread.

**/ private static final ThreadLocal HLDACMT = new ThreadLocal() { }; /** *

SQLite database (connection like) per thread holder.

**/ private static final ThreadLocal HLDSQLT = new ThreadLocal() { }; /** *

Get autocommit flag.

* @throws Exception - an exception **/ @Override public final boolean getAcmt() throws Exception { Boolean acmt = HLDACMT.get(); if (acmt == null) { acmt = Boolean.TRUE; HLDACMT.set(acmt); } return acmt; } /** *

Sets autocommit flag.

* @param pAcmt if autocommit * @throws Exception - an exception **/ @Override public final void setAcmt(final boolean pAcmt) throws Exception { HLDACMT.set(pAcmt); } /** *

Sets transaction isolation level. * Either read-uncommited or serializable.

* @param pLevel transaction level * @throws Exception - an exception **/ @Override public final void setTrIsl(final int pLevel) throws Exception { Integer val; if (pLevel == TRSR) { val = 0; } else { val = 1; } exec("PRAGMA read_uncommitted=" + val + ";"); } /** *

Gets transaction isolation level.

* @return Level transaction * @throws Exception - an exception **/ @Override public final int getTrIsl() throws Exception { Integer val = evInt("PRAGMA read_uncommitted;", "read_uncommitted"); if (val == null || val == 0) { return TRSR; } else { return TRRUC; } } /** *

Creates savepoint.

* @param pSvpNm savepoint name * @throws Exception - an exception **/ @Override public final void creSavPnt( final String pSvpNm) throws Exception { exec("SAVEPOINT " + pSvpNm + ";"); } /** *

Releases savepoint.

* @param pSvpNm savepoint name * @throws Exception - an exception **/ @Override public final void relSavPnt( final String pSvpNm) throws Exception { exec("RELEASE " + pSvpNm + ";"); } /** *

Rollbacks transaction to savepoint.

* @param pSvpNm savepoint name * @throws Exception - an exception **/ @Override public final void rollBack( final String pSvpNm) throws Exception { exec(";ROLLBACK TRANSACTION TO SAVEPOINT " + pSvpNm + ";"); } /** *

Starts new transaction.

* @throws Exception - an exception **/ @Override public final void begin() throws Exception { exec("BEGIN TRANSACTION;"); } /** *

Commits transaction and unlocks this service.

* @throws Exception - an exception **/ @Override public final void commit() throws Exception { exec("COMMIT TRANSACTION;"); } /** *

Rollbacks transaction.

* @throws Exception - an exception **/ @Override public final void rollBack() throws Exception { exec("ROLLBACK TRANSACTION;"); } /** *

Closes DB.

* @throws Exception - an exception **/ @Override public final void release() throws Exception { SQLiteDatabase sqliteDb = HLDSQLT.get(); if (sqliteDb != null) { sqliteDb.close(); HLDSQLT.remove(); boolean dbgSh = getLog().getDbgSh(this.getClass(), 16008); if (dbgSh) { getLog().debug(null, getClass(), "Release DB OK"); } } } /** *

Retrieves records from DB.

* @param pSelect query SELECT * @return IRecSet record set * @throws Exception - if an exception occurred **/ @Override public final IRecSet retRs( final String pSelect) throws Exception { boolean dbgSh = getLog().getDbgSh(this.getClass(), 16000); try { if (dbgSh) { getLog().debug(null, getClass(), "try to retrieve records: " + pSelect); } Cursor rs = lazDb().rawQuery(pSelect, null); RecSet rsa = new RecSet(rs); if (dbgSh) { getLog().debug(null, getClass(), "Recordset: " + rsStr(rsa)); } return rsa; } catch (Exception ex) { String msg = ex.getMessage() + ", query:\n" + pSelect; ExcCode ewc = new ExcCode(SQLEX, msg); ewc.setStackTrace(ex.getStackTrace()); throw ewc; } } /** *

Executes any SQL query that returns no data. * E.g. PRAGMA, etc.

* @param pQuery query * @throws Exception - if an exception occurred **/ @Override public final void exec(final String pQuery) throws Exception { boolean dbgSh = getLog().getDbgSh(this.getClass(), 16001); try { if (dbgSh) { getLog().debug(null, getClass(), "try to execute query: " + pQuery); } lazDb().execSQL(pQuery); } catch (Exception ex) { String msg = ex.getMessage() + ", query:\n" + pQuery; ExcCode ewc = new ExcCode(SQLEX, msg); ewc.setStackTrace(ex.getStackTrace()); throw ewc; } } /** *

Executes SQL UPDATE that returns affected rows. * It is to adapt Android insert/update/delete interface. *

* @param entity type * @param pCls entity class * @param pCv type-safe map column name - column value * @param pWhe where conditions e.g. "itsId=2" * @return row count affected * @throws Exception - if an exception occurred **/ @Override public final > int update(final Class pCls, final ColVals pCv, final String pWhe) throws Exception { boolean dbgSh = getLog().getDbgSh(this.getClass(), 16002); try { ContentValues cntVals = cnvToCntValsUpd(pCls, pCv); if (dbgSh) { getLog().debug(null, getClass(), "try to update : " + pCls + " where: " + pWhe + " cv: " + getSrvClVl().str(pCls, pCv) + ", ACV: " + cntVals); } return lazDb().update(pCls.getSimpleName().toUpperCase(Locale.ROOT), cntVals, pWhe, null); } catch (Exception ex) { String msg = ex.getMessage() + ", cls: " + pCls + ", cv: " + getSrvClVl().str(pCls, pCv) + ", where: " + pWhe; ExcCode ewc = new ExcCode(SQLEX, msg); ewc.setStackTrace(ex.getStackTrace()); throw ewc; } } /** *

Executes SQL INSERT that returns affected rows. * It is to adapt Android insert/update/delete interface. *

* @param entity type * @param pCls entity class * @param pCv type-safe map column name - column value * @return Number inserted row (auto-generated or not) or -1 if error * @throws Exception - if an exception occurred **/ @Override public final > long insert(final Class pCls, final ColVals pCv) throws Exception { boolean dbgSh = getLog().getDbgSh(this.getClass(), 16003); try { ContentValues cntVals = cnvToCntValsIns(pCls, pCv); if (dbgSh) { getLog().debug(null, getClass(), "try to insert : " + pCls + " cv: " + getSrvClVl().str(pCls, pCv) + " ACV: " + cntVals); } long result = lazDb() .insert(pCls.getSimpleName().toUpperCase(Locale.ROOT), null, cntVals); if (dbgSh) { getLog().debug(null, getClass(), "result insert: " + result); } if (result == -1) { throw new Exception("Result = -1!"); } return result; } catch (Exception ex) { String msg = ex.getMessage() + ", cls: " + pCls + ", cv: " + getSrvClVl().str(pCls, pCv); ExcCode ewc = new ExcCode(SQLEX, msg); ewc.setStackTrace(ex.getStackTrace()); throw ewc; } } /** *

Executes SQL DELETE that returns affected rows. * It is to adapt Android insert/update/delete interface. *

* @param pTbl table name * @param pWhe where conditions e.g. "itsId=2" or NULL -delete all * @return row count affected * @throws Exception - if an exception occurred **/ @Override public final int delete(final String pTbl, final String pWhe) throws Exception { boolean dbgSh = getLog().getDbgSh(this.getClass(), 16004); try { if (dbgSh) { getLog().debug(null, getClass(), "try to delete t: " + pTbl + " where: " + pWhe); } return lazDb().delete(pTbl, pWhe, null); } catch (Exception ex) { String msg = ex.getMessage() + ", table: " + pTbl + ", where: " + pWhe; ExcCode ewc = new ExcCode(SQLEX, msg); ewc.setStackTrace(ex.getStackTrace()); throw ewc; } } /** *

Lazy gets database for thread.

* @return SQLite DB **/ private SQLiteDatabase lazDb() { SQLiteDatabase sqliteDb = HLDSQLT.get(); if (sqliteDb == null) { sqliteDb = this.sqliteOh.getWritableDatabase(); HLDSQLT.set(sqliteDb); } return sqliteDb; } //Simple getters and setters: /** *

Getter for sqliteOh.

* @return SQLiteOpenHelper **/ public final SQLiteOpenHelper getSqliteOh() { return this.sqliteOh; } /** *

Setter for sqliteOh.

* @param pSqliteOh reference **/ public final void setSqliteOh(final SQLiteOpenHelper pSqliteOh) { this.sqliteOh = pSqliteOh; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy