platform/shared/rubyJVM/src/com/rho/db/DBAdapter.java in rhodes-1.5.5 vs platform/shared/rubyJVM/src/com/rho/db/DBAdapter.java in rhodes-2.0.0.beta1
- old
+ new
@@ -1,44 +1,52 @@
package com.rho.db;
import com.xruby.runtime.builtin.*;
import com.xruby.runtime.lang.*;
import com.rho.*;
+import com.rho.file.*;
+
+import java.util.Enumeration;
import java.util.Vector;
+import java.util.Hashtable;
-public class DBAdapter extends RubyBasic {
+public class DBAdapter extends RubyBasic
+{
private static final RhoLogger LOG = RhoLogger.RHO_STRIP_LOG ? new RhoEmptyLogger() :
new RhoLogger("DbAdapter");
- private static DBAdapter m_Instance;
+ //private static DBAdapter m_Instance;
private IDBStorage m_dbStorage;
private boolean m_bIsOpen = false;
private String m_strDBPath;
private String m_strDBVerPath;
private DBAttrManager m_attrMgr = new DBAttrManager();
+ static Hashtable/*Ptr<String,CDBAdapter*>*/ m_mapDBPartitions = new Hashtable();
Mutex m_mxDB = new Mutex();
int m_nTransactionCounter=0;
boolean m_bUIWaitDB = false;
+ static Hashtable/*Ptr<String,CDBAdapter*>&*/ getDBPartitions(){ return m_mapDBPartitions; }
+
DBAdapter(RubyClass c) {
super(c);
try{
m_dbStorage = RhoClassFactory.createDBStorage();
}catch(Exception exc){
LOG.ERROR("createDBStorage failed.", exc);
}
}
-
+/*
public static DBAdapter getInstance(){
if ( m_Instance == null )
m_Instance = new DBAdapter(RubyRuntime.DatabaseClass);
return m_Instance;
- }
+ }*/
public void close()
{
try{
m_dbStorage.close();
@@ -51,19 +59,33 @@
public DBAttrManager getAttrMgr()
{
return m_attrMgr;
}
+
+ public void executeBatchSQL(String strStatement)throws DBException{
+ LOG.TRACE("executeBatchSQL: " + strStatement);
+
+ m_dbStorage.executeBatchSQL(strStatement);
+ }
public IDBResult executeSQL(String strStatement, Object[] values)throws DBException{
LOG.TRACE("executeSQL: " + strStatement);
-
- return m_dbStorage.executeSQL(strStatement,values,false);
+ IDBResult res = null;
+ Lock();
+ try{
+ res = m_dbStorage.executeSQL(strStatement,values,false);
+ }finally
+ {
+ Unlock();
+ }
+ return res;
}
public IDBResult executeSQL(String strStatement)throws DBException{
return executeSQL(strStatement,null);
}
+
public IDBResult executeSQL(String strStatement, Object arg1)throws DBException{
Object[] values = {arg1};
return executeSQL(strStatement,values);
}
public IDBResult executeSQL(String strStatement, int arg1)throws DBException{
@@ -96,42 +118,88 @@
public IDBResult executeSQL(String strStatement, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6)throws DBException{
Object[] values = {arg1,arg2,arg3,arg4,arg5,arg6};
return executeSQL(strStatement,values);
}
- public IDBResult executeSQLReportNonUnique(String strStatement, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6)throws DBException{
+ public IDBResult executeSQLReportNonUnique(String strStatement, Object arg1, Object arg2, Object arg3, Object arg4)throws DBException{
LOG.TRACE("executeSQLReportNonUnique: " + strStatement);
- Object[] values = {arg1,arg2,arg3,arg4,arg5,arg6};
- return m_dbStorage.executeSQL(strStatement,values, true);
+ Object[] values = {arg1,arg2,arg3,arg4};
+ IDBResult res = null;
+ Lock();
+ try{
+ res = m_dbStorage.executeSQL(strStatement,values, true);
+ }finally
+ {
+ Unlock();
+ }
+
+ return res;
}
+
+ public IDBResult executeSQLReportNonUniqueEx(String strStatement, Vector vecValues)throws DBException{
+ LOG.TRACE("executeSQLReportNonUnique: " + strStatement);
+
+ Object[] values = new Object[vecValues.size()];
+ for (int i = 0; i < vecValues.size(); i++ )
+ values[i] = vecValues.elementAt(i);
+
+ IDBResult res = null;
+ Lock();
+ try{
+ res = m_dbStorage.executeSQL(strStatement,values, true);
+ }finally
+ {
+ Unlock();
+ }
+
+ return res;
+ }
+ public IDBResult executeSQLEx(String strStatement, Vector vecValues)throws DBException{
+ Object[] values = new Object[vecValues.size()];
+ for (int i = 0; i < vecValues.size(); i++ )
+ values[i] = vecValues.elementAt(i);
+
+ return executeSQL(strStatement,values);
+ }
+
public IDBResult executeSQL(String strStatement, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7)throws DBException{
Object[] values = {arg1,arg2,arg3,arg4,arg5,arg6,arg7};
return executeSQL(strStatement,values);
}
public boolean isUIWaitDB(){ return m_bUIWaitDB; }
- public void setUIWaitDB(boolean b){ m_bUIWaitDB = b; }
- public void Lock(){ m_mxDB.Lock(); }
+ public void Lock()
+ {
+ if ( RhoRuby.isMainRubyThread() )
+ m_bUIWaitDB = true;
+
+ m_mxDB.Lock();
+
+ if ( RhoRuby.isMainRubyThread() )
+ m_bUIWaitDB = false;
+ }
+
public void Unlock(){ m_mxDB.Unlock(); }
public boolean isInsideTransaction(){ return m_nTransactionCounter>0; }
- public static IDBResult createResult(){
- return getInstance().m_dbStorage.createResult();
- }
+ //public static IDBResult createResult(){
+ // return getInstance().m_dbStorage.createResult();
+ //}
public static String makeBlobFolderName()throws Exception{
- String fName = RhoClassFactory.createFile().getDirPath("apps/public/db-files");
+ String fName = RhoClassFactory.createFile().getDirPath("db/db-files");
+
return fName;
}
- RubyString[] getColNames(IDBResult rows)
+ RubyString[] getOrigColNames(IDBResult rows)
{
RubyString[] colNames = new RubyString[rows.getColCount()];
for ( int nCol = 0; nCol < rows.getColCount(); nCol ++ )
- colNames[nCol] = ObjectFactory.createString(rows.getColName(nCol));
+ colNames[nCol] = ObjectFactory.createString(rows.getOrigColName(nCol));
return colNames;
}
private String getNameNoExt(String strPath){
@@ -172,27 +240,35 @@
public void startTransaction()throws DBException
{
Lock();
m_nTransactionCounter++;
-
if (m_nTransactionCounter == 1)
- m_dbStorage.startTransaction();
+ m_dbStorage.startTransaction();
}
public void commit()throws DBException
{
m_nTransactionCounter--;
-
if (m_nTransactionCounter == 0)
{
getAttrMgr().save(this);
m_dbStorage.commit();
}
Unlock();
}
+
+ public void rollback()throws DBException
+ {
+ m_nTransactionCounter--;
+ if (m_nTransactionCounter == 0)
+ m_dbStorage.rollback();
+
+ Unlock();
+ }
+
public void endTransaction()throws DBException
{
commit();
}
@@ -380,10 +456,43 @@
writeDBVersion(new DBVersion(strRhoDBVer, strAppDBVer) );
}
}
+ static Vector m_dbAdapters = new Vector();
+
+ public static DBAdapter findDBAdapterByBaseName(String strBaseName)
+ {
+ for ( int i = 0; i < m_dbAdapters.size(); i++ )
+ {
+ DBAdapter item = (DBAdapter)m_dbAdapters.elementAt(i);
+ FilePath oPath = new FilePath(item.getDBPath());
+
+ if ( oPath.getBaseName().compareTo(strBaseName) == 0 )
+ return item;
+ }
+ return null;
+ }
+
+ public static void startAllDBTransaction()throws DBException
+ {
+ for ( int i = 0; i < m_dbAdapters.size(); i++ )
+ {
+ DBAdapter item = (DBAdapter)m_dbAdapters.elementAt(i);
+ item.startTransaction();
+ }
+ }
+
+ public static void commitAllDBTransaction()throws DBException
+ {
+ for ( int i = 0; i < m_dbAdapters.size(); i++ )
+ {
+ DBAdapter item = (DBAdapter)m_dbAdapters.elementAt(i);
+ item.commit();
+ }
+ }
+
private void openDB(String strDBName)throws Exception
{
if ( m_bIsOpen )
return;
@@ -395,10 +504,12 @@
m_bIsOpen = true;
getAttrMgr().load(this);
m_dbStorage.setDbCallback(new DBCallback(this));
+
+ m_dbAdapters.addElement(this);
}
private String createInsertStatement(IDBResult res, String tableName)
{
String strInsert = "INSERT INTO ";
@@ -420,20 +531,52 @@
strInsert += strQuest + ")";
return strInsert;
}
- private RubyValue rb_destroy_table(RubyValue v)
+ private boolean destroyTableName(String tableName, Vector arIncludeTables, Vector arExcludeTables )
+ {
+ int i;
+ for (i = 0; i < (int)arExcludeTables.size(); i++ )
+ {
+ if ( ((String)arExcludeTables.elementAt(i)).equalsIgnoreCase(tableName) )
+ return false;
+ }
+
+ for (i = 0; i < (int)arIncludeTables.size(); i++ )
+ {
+ if ( ((String)arIncludeTables.elementAt(i)).equalsIgnoreCase(tableName) )
+ return true;
+ }
+
+ return arIncludeTables.size()==0;
+ }
+
+ public boolean isTableExist(String strTableName)throws DBException
+ {
+ String[] vecTables = m_dbStorage.getAllTableNames();
+ for ( int i = 0; i< vecTables.length; i++ )
+ {
+ String tableName = vecTables[i];
+ if ( tableName.equalsIgnoreCase(strTableName) )
+ return true;
+ }
+
+ return false;
+ }
+
+ private RubyValue rb_destroy_tables(RubyValue vInclude, RubyValue vExclude)
{
if ( !m_bIsOpen )
return RubyConstant.QNIL;
IDBStorage db = null;
try{
getAttrMgr().reset(this);
- String strTable = v.toStr();
+ Vector vecIncludes = RhoRuby.makeVectorStringFromArray(vInclude);
+ Vector vecExcludes = RhoRuby.makeVectorStringFromArray(vExclude);
String dbName = getNameNoExt(m_strDBPath);
String dbNewName = dbName + "new";
IFileAccess fs = RhoClassFactory.createFileAccess();
@@ -465,11 +608,11 @@
db.startTransaction();
for ( int i = 0; i< vecTables.length; i++ )
{
String tableName = vecTables[i];
- if ( tableName.equalsIgnoreCase(strTable) )
+ if ( destroyTableName( tableName, vecIncludes, vecExcludes ) )
continue;
res = executeSQL("SELECT * from " + tableName, null);
String strInsert = "";
for ( ; !res.isEnd(); res.next() )
@@ -537,22 +680,12 @@
}
return RubyConstant.QNIL;
}
- public void rollback()throws DBException
+ public void setBulkSyncDB(String fDbName, String fScriptName)
{
- m_nTransactionCounter--;
-
- if (m_nTransactionCounter == 0)
- m_dbStorage.rollback();
-
- Unlock();
- }
-
- public void setInitialSyncDB(String fDbName, String fScriptName)
- {
IDBStorage db = null;
try{
db = RhoClassFactory.createDBStorage();
db.open( fDbName, "" );
@@ -571,18 +704,36 @@
db.executeSQL(strInsert, res.getCurData(), false );
}
}
//copy sources
{
- IDBResult res = executeSQL("SELECT name, source_url,priority,session from sources", null);
+ String tableName = "sources";
+ String strSelect = "SELECT * from " + tableName;
+ IDBResult res = executeSQL( strSelect );
+ String strInsert = "";
for ( ; !res.isEnd(); res.next() )
{
- String strName = res.getStringByIdx(0);
- Object[] values = {res.getStringByIdx(1), new Integer(res.getIntByIdx(2)),res.getStringByIdx(3),strName};
+ String strName = res.getStringByIdx(1);
+ Object[] values = {strName};
+ IDBResult res2 = db.executeSQL("SELECT name from sources where name=?", values, false);
+ if (!res2.isEnd())
+ continue;
+
+ if ( strInsert.length() == 0 )
+ strInsert = createInsertStatement(res, tableName);
- db.executeSQL("UPDATE sources SET source_url=?,priority=?,session=? where name=?",values, false);
+ db.executeSQL(strInsert, res.getCurData(), false );
}
+/*
+ IDBResult res = executeSQL("SELECT name, sync_type, partition, priority from sources", null);
+ for ( ; !res.isEnd(); res.next() )
+ {
+ String strName = res.getStringByIdx(0);
+ Object[] values = {res.getStringByIdx(1), new Integer(res.getIntByIdx(2)),new Integer(res.getIntByIdx(3)),strName};
+
+ db.executeSQL("UPDATE sources SET sync_type=?, partition=?, priority=? where name=?",values, false);
+ }*/
}
db.commit();
db.close();
@@ -666,55 +817,54 @@
}
return res;
}*/
- public RubyValue rb_execute(RubyValue v, RubyValue arg)
+ public RubyValue rb_execute(RubyValue v, RubyValue batch, RubyValue arg)
{
RubyArray res = new RubyArray();
try{
- Object[] values = null;
- if ( arg != null )
+ String strSql = v.toStr();
+ if ( batch == RubyConstant.QTRUE )
{
- RubyArray args1 = arg.toAry();
- RubyArray args = args1;
- if ( args.size() > 0 && args.get(0) instanceof RubyArray )
- args = (RubyArray)args.get(0);
-
- values = new Object[args.size()];
- for ( int i = 0; i < args.size(); i++ )
+ LOG.INFO("batch execute:" + strSql);
+
+ executeBatchSQL( strSql );
+ }
+ else
+ {
+ Object[] values = null;
+ if ( arg != null )
{
- RubyValue val = args.get(i);
- if ( val instanceof RubyFixnum )
- values[i] = new Long( ((RubyFixnum)val).toLong() );
- else
- values[i] = val.toString();
+ RubyArray args1 = arg.toAry();
+ RubyArray args = args1;
+ if ( args.size() > 0 && args.get(0) instanceof RubyArray )
+ args = (RubyArray)args.get(0);
+
+ values = new Object[args.size()];
+ for ( int i = 0; i < args.size(); i++ )
+ {
+ RubyValue val = args.get(i);
+ if ( val instanceof RubyFixnum )
+ values[i] = new Long( ((RubyFixnum)val).toLong() );
+ else
+ values[i] = val.toString();
+ }
}
- }
-
- setUIWaitDB(true);
- Lock();
-
- try{
- IDBResult rows = executeSQL(v.toStr(), values);
-
- RubyString[] colNames = getColNames(rows);
+ IDBResult rows = executeSQL( strSql, values);
+ RubyString[] colNames = getOrigColNames(rows);
+
for( ; !rows.isEnd(); rows.next() )
{
RubyHash row = ObjectFactory.createHash();
for ( int nCol = 0; nCol < rows.getColCount(); nCol ++ )
row.add( colNames[nCol], rows.getRubyValueByIdx(nCol) );
res.add( row );
}
- }finally
- {
- setUIWaitDB(false);
- Unlock();
- }
-
+ }
}catch(Exception e)
{
LOG.ERROR("execute failed.", e);
throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
}
@@ -722,128 +872,200 @@
return res;
}
//@RubyAllocMethod
private static RubyValue alloc(RubyValue receiver) {
- return getInstance();
+ return new DBAdapter(RubyRuntime.DatabaseClass);
}
- private RubyValue rb_initialize(RubyValue v)
+ public static void closeAll()
{
- try{
- openDB(v !=null && v != RubyConstant.QNIL ? v.toString() : "");
- }catch(Exception e)
+ Enumeration enumDBs = m_mapDBPartitions.elements();
+ while (enumDBs.hasMoreElements())
{
- LOG.ERROR("initialize failed.", e);
- throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
+ DBAdapter db = (DBAdapter)enumDBs.nextElement();
+ db.close();
}
-
- return this;
}
-
- private RubyValue rb_start_transaction() {
- try{
- setUIWaitDB(true);
- startTransaction();
- }catch( Exception e ){
- LOG.ERROR("start_transaction failed.", e);
- throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
- }
-
- return ObjectFactory.createInteger(0);
+
+ public static void initAttrManager()throws DBException
+ {
+ Enumeration enumDBs = m_mapDBPartitions.elements();
+ while (enumDBs.hasMoreElements())
+ {
+ DBAdapter db = (DBAdapter)enumDBs.nextElement();
+ db.getAttrMgr().loadBlobAttrs(db);
+ }
}
- private RubyValue rb_commit() {
- try{
- commit();
- }catch( Exception e ){
- LOG.ERROR("commit failed.", e);
- throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
- }
-
- return ObjectFactory.createInteger(0);
+ public static DBAdapter getUserDB()
+ {
+ return (DBAdapter)getDBPartitions().get("user");
}
-
- private RubyValue rb_rollback() {
- try{
- rollback();
- }catch( Exception e ){
- LOG.ERROR("rollback failed.", e);
- throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
- }
-
- return ObjectFactory.createInteger(0);
+
+ public static DBAdapter getDB(String szPartition)
+ {
+ return (DBAdapter)getDBPartitions().get(szPartition);
}
-
- private RubyValue rb_close() {
- try{
-
- //do not close sync db, close it at exit
- /*if ( m_dbStorage != null ){
- m_dbStorage.close();
- m_dbStorage = null;
- }*/
-
- }catch( Exception e ){
- LOG.ERROR("close failed.", e);
- throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
- }
-
- return ObjectFactory.createInteger(0);
+
+ public static boolean isAnyInsideTransaction()
+ {
+ Enumeration enumDBs = m_mapDBPartitions.elements();
+ while (enumDBs.hasMoreElements())
+ {
+ DBAdapter db = (DBAdapter)enumDBs.nextElement();
+
+ if ( db.isInsideTransaction() )
+ return true;
+ }
+
+ return false;
}
public static void initMethods(RubyClass klass) {
klass.defineAllocMethod(new RubyNoArgMethod(){
protected RubyValue run(RubyValue receiver, RubyBlock block ) {
return DBAdapter.alloc(receiver);}
});
- klass.defineMethod( "initialize", new RubyOneArgMethod(){
- protected RubyValue run(RubyValue receiver, RubyValue arg, RubyBlock block ){
- return ((DBAdapter)receiver).rb_initialize(arg);}
+ klass.defineMethod( "initialize", new RubyTwoArgMethod()
+ {
+ protected RubyValue run(RubyValue receiver, RubyValue arg1, RubyValue arg2, RubyBlock block )
+ {
+ try
+ {
+ String szDbName = arg1.toStr();
+ String szDbPartition = arg2.toStr();
+ ((DBAdapter)receiver).openDB(szDbName);
+
+ DBAdapter.getDBPartitions().put(szDbPartition, receiver);
+
+ return receiver;
+ }catch(Exception e)
+ {
+ LOG.ERROR("initialize failed.", e);
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
+ }
+
+ }
});
- klass.defineMethod( "close", new RubyNoArgMethod(){
+ /*klass.defineMethod( "close", new RubyNoArgMethod(){
protected RubyValue run(RubyValue receiver, RubyBlock block ){
return ((DBAdapter)receiver).rb_close();}
- });
+ });*/
klass.defineMethod( "execute", new RubyVarArgMethod(){
protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block ){
- return ((DBAdapter)receiver).rb_execute(args.get(0),
- (args.size() > 1 ? args.get(1):null));}
+ return ((DBAdapter)receiver).rb_execute(args.get(0), args.get(1),
+ (args.size() > 2 ? args.get(2):null));}
});
klass.defineMethod( "start_transaction", new RubyNoArgMethod(){
- protected RubyValue run(RubyValue receiver, RubyBlock block ){
- return ((DBAdapter)receiver).rb_start_transaction();}
+ protected RubyValue run(RubyValue receiver, RubyBlock block )
+ {
+ try{
+ ((DBAdapter)receiver).startTransaction();
+ return ObjectFactory.createInteger(0);
+ }catch( Exception e ){
+ LOG.ERROR("start_transaction failed.", e);
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
+ }
+ }
});
klass.defineMethod( "commit", new RubyNoArgMethod(){
- protected RubyValue run(RubyValue receiver, RubyBlock block ){
- return ((DBAdapter)receiver).rb_commit();}
+ protected RubyValue run(RubyValue receiver, RubyBlock block )
+ {
+ try{
+ ((DBAdapter)receiver).commit();
+ return ObjectFactory.createInteger(0);
+ }catch( Exception e ){
+ LOG.ERROR("commit failed.", e);
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
+ }
+ }
});
klass.defineMethod( "rollback", new RubyNoArgMethod(){
- protected RubyValue run(RubyValue receiver, RubyBlock block ){
- return ((DBAdapter)receiver).rb_rollback();}
- });
- klass.defineMethod( "destroy_table", new RubyOneArgMethod(){
- protected RubyValue run(RubyValue receiver, RubyValue arg, RubyBlock block ){
- return ((DBAdapter)receiver).rb_destroy_table(arg);}
- });
- klass.defineMethod( "is_ui_waitfordb", new RubyNoArgMethod(){
protected RubyValue run(RubyValue receiver, RubyBlock block )
{
- try{
- boolean bRes = ((DBAdapter)receiver).isUIWaitDB();
-
- return ObjectFactory.createBoolean(bRes);
+ try{
+ ((DBAdapter)receiver).rollback();
+ return ObjectFactory.createInteger(0);
}catch( Exception e ){
- LOG.ERROR("is_ui_waitfordb failed.", e);
+ LOG.ERROR("rollback failed.", e);
throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
}
}
});
+ klass.defineMethod( "destroy_tables", new RubyTwoArgMethod(){
+ protected RubyValue run(RubyValue receiver, RubyValue arg, RubyValue arg1, RubyBlock block ){
+ return ((DBAdapter)receiver).rb_destroy_tables(arg, arg1);}
+ });
+ klass.defineMethod("is_ui_waitfordb", new RubyNoArgMethod() {
+ protected RubyValue run(RubyValue receiver, RubyBlock block)
+ {
+ try{
+ boolean bRes = ((DBAdapter)receiver).isUIWaitDB();
+ return ObjectFactory.createBoolean(bRes);
+ }catch(Exception e)
+ {
+ LOG.ERROR("is_ui_waitfordb failed", e);
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
+ }
+ }
+ });
+
+/*
+ klass.defineMethod("lock_db",
+ new RubyNoArgMethod() {
+ protected RubyValue run(RubyValue receiver, RubyBlock block) {
+ try{
+ DBAdapter db = (DBAdapter)receiver;
+ db.setUnlockDB(true);
+ db.Lock();
+ }catch(Exception e)
+ {
+ LOG.ERROR("lock_db failed", e);
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
+ }
+
+ return RubyConstant.QNIL;
+ }
+ });
+ klass.defineMethod("unlock_db",
+ new RubyNoArgMethod() {
+ protected RubyValue run(RubyValue receiver, RubyBlock block) {
+ try{
+ DBAdapter db = (DBAdapter)receiver;
+ db.Unlock();
+ }catch(Exception e)
+ {
+ LOG.ERROR("unlock_db failed", e);
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
+ }
+
+ return RubyConstant.QNIL;
+ }
+ });
+*/
+
+ klass.defineMethod( "table_exist?", new RubyOneArgMethod(){
+ protected RubyValue run(RubyValue receiver, RubyValue arg, RubyBlock block )
+ {
+ try{
+ DBAdapter db = (DBAdapter)receiver;
+ boolean bExists = db.isTableExist(arg.toStr());
+
+ return ObjectFactory.createBoolean(bExists);
+ }catch(Exception e)
+ {
+ LOG.ERROR("unlock_db failed", e);
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
+ }
+ }
+ });
+
}
public static class DBCallback implements IDBCallback
{
private DBAdapter m_db;
@@ -863,55 +1085,118 @@
}catch(Exception exc){
LOG.ERROR("DBCallback.OnDeleteAllFromTable: Error delete files from table: " + tableName, exc);
}
}*/
- public void OnInsertIntoTable(String tableName, IDBResult rows2Insert)
+ public void onAfterInsert(String tableName, IDBResult rows2Insert)
{
if ( !tableName.equalsIgnoreCase("object_values") )
return;
for( ; !rows2Insert.isEnd(); rows2Insert.next() )
{
- int nSrcID = rows2Insert.getIntByIdx(1);
- String name = rows2Insert.getStringByIdx(2);
- m_db.getAttrMgr().add(nSrcID, name);
+ Object[] data = rows2Insert.getCurData();
+ Integer nSrcID = new Integer(rows2Insert.getIntByIdx(0));
+ String attrib = (String)data[1];
+ m_db.getAttrMgr().add(nSrcID, attrib);
}
}
- public void OnDeleteFromTable(String tableName, IDBResult rows2Delete)
+ public void onBeforeUpdate(String tableName, IDBResult rows2Delete, int[] cols)
{
- if ( !tableName.equalsIgnoreCase("object_values") )
+ processDelete(tableName, rows2Delete, cols);
+ }
+
+ public void onBeforeDelete(String tableName, IDBResult rows2Delete)
+ {
+ processDelete(tableName, rows2Delete, null);
+ }
+
+ private boolean isChangedCol(int[] cols, int iCol)
+ {
+ if (cols==null)
+ return true;
+
+ for ( int i = 0; i < cols.length; i++ )
+ {
+ if ( cols[i] == iCol )
+ return true;
+ }
+ return false;
+ }
+
+ private void processDelete(String tableName, IDBResult rows2Delete, int[] cols)
+ {
+ if ( tableName.equalsIgnoreCase("changed_values") || tableName.equalsIgnoreCase("sources") ||
+ tableName.equalsIgnoreCase("client_info"))
return;
+ boolean bProcessTable = tableName.equalsIgnoreCase("object_values");
+ boolean bSchemaSrc = false;
+ Integer nSrcID = null;
+ if ( !bProcessTable )
+ {
+ nSrcID = m_db.getAttrMgr().getSrcIDHasBlobsByName(tableName);
+ bProcessTable = nSrcID != null;
+ bSchemaSrc = bProcessTable;
+ }
+
+ if ( !bProcessTable)
+ return;
+
+ if ( !bSchemaSrc && !isChangedCol(cols, 3))//value
+ return;
+
for( ; !rows2Delete.isEnd(); rows2Delete.next() )
{
- int nSrcID = rows2Delete.getIntByIdx(1);
- String attrib = rows2Delete.getStringByIdx(2);
- m_db.getAttrMgr().remove(nSrcID, attrib);
+ Object[] data = rows2Delete.getCurData();
- String attrib_type = rows2Delete.getStringByIdx(5);
- if ( !attrib_type.equals("blob.file") )
- continue;
+ if ( !bSchemaSrc )
+ {
+ if ( nSrcID == null )
+ nSrcID = new Integer(rows2Delete.getIntByIdx(0));
+
+ String attrib = (String)data[1];
+ String value = (String)data[3];
- String url = rows2Delete.getStringByIdx(4);
- if ( url == null || url.length() == 0 )
- continue;
-
- try{
- SimpleFile oFile = RhoClassFactory.createFile();
-
- String strFilePath = oFile.getDirPath("");
- strFilePath += url.startsWith("/") ? url.substring(1) : url;
-
- oFile.delete(strFilePath);
- }catch(Exception exc){
- LOG.ERROR("DBCallback.OnDeleteFromTable: Error delete file: " + url, exc);
+ if (cols == null) //delete
+ m_db.getAttrMgr().remove(nSrcID, attrib);
+
+ if ( m_db.getAttrMgr().isBlobAttr(nSrcID, attrib) )
+ processBlobDelete(nSrcID, attrib, value);
+ }else
+ {
+ for ( int i = 0; i < rows2Delete.getColCount(); i++ )
+ {
+ if (!isChangedCol(cols, i))
+ continue;
+
+ String attrib = rows2Delete.getColName(i);
+ if ( !(data[i] instanceof String) )
+ continue;
+
+ String value = (String)data[i];
+ if ( m_db.getAttrMgr().isBlobAttr(nSrcID, attrib) )
+ processBlobDelete(nSrcID, attrib, value);
+ }
}
-
}
}
+ private void processBlobDelete(Integer nSrcID, String attrib, String value)
+ {
+ if ( value == null || value.length() == 0 )
+ return;
+
+ try{
+ String strFilePath = RhodesApp.getInstance().resolveDBFilesPath(value);
+
+ SimpleFile oFile = RhoClassFactory.createFile();
+ oFile.delete(strFilePath);
+ }catch(Exception exc){
+ LOG.ERROR("DBCallback.OnDeleteFromTable: Error delete file: " + value, exc);
+ }
+ }
+
}
-
-}
+}
\ No newline at end of file