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