/ *
XOWA: the XOWA Offline Wiki Application
Copyright ( C ) 2012 gnosygnu @gmail.com
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation , either version 3 of the
License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Affero General Public License for more details .
You should have received a copy of the GNU Affero General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
package gplx.core.stores ; import gplx.* ; import gplx.core.* ;
import gplx.core.criterias.* ; import gplx.dbs.* ; import gplx.core.gfo_ndes.* ;
public class DbMaprRdr extends DataRdr_base implements SrlMgr {
@Override public String NameOfNode ( ) { return "DbMaprRdr" ; }
@Override public Object StoreRoot ( SrlObj subProto , String key ) {
mgr = ( DbMaprMgr ) this . EnvVars ( ) . Get_by_or_fail ( DbMaprWtr . Key_Mgr ) ;
DbMaprItm rootMapr = mgr . Root ( ) ;
GfoNde tbl = GetTbl ( rootMapr , rootCrt ) ; int subsCount = tbl . Subs ( ) . Count ( ) ; if ( subsCount = = 0 ) return null ; if ( subsCount > 1 ) throw Err_ . new_wo_type ( "criteria returned > 1 row" , "criteria" , rootCrt . To_str ( ) , "subsCount" , subsCount ) ;
SrlObj root = subProto . SrlObj_New ( null ) ;
mgr . EnvStack_add ( rootMapr , root ) ; RowStack_add ( tbl , 0 ) ;
root . SrlObj_Srl ( this ) ;
mgr . Clear ( ) ; rowStack . Clear ( ) ;
return root ;
}
@Override public void SrlList ( String subPropKey , List_adp list , SrlObj subProto , String itmKey ) {
DbMaprItm curMapr = ( DbMaprItm ) mgr . MaprStack ( ) . Get_at_last ( ) ;
DbMaprItm subMapr = curMapr . Subs_get ( subPropKey ) ;
list . Clear ( ) ;
Criteria crit = MakeCrt ( mgr , subMapr ) ;
GfoNde tbl = GetTbl ( subMapr , crit ) ;
int tblLen = tbl . Subs ( ) . Count ( ) ;
for ( int i = 0 ; i < tblLen ; i + + ) {
SrlObj sub = ( SrlObj ) subProto . SrlObj_New ( null ) ;
GfoNde subRow = tbl . Subs ( ) . FetchAt_asGfoNde ( i ) ;
mgr . EnvStack_add ( subMapr , sub ) ; rowStack . Add ( subRow ) ;
sub . SrlObj_Srl ( this ) ; list . Add ( sub ) ;
mgr . EnvStack_del ( subMapr , sub ) ; List_adp_ . DelAt_last ( rowStack ) ;
}
}
Criteria MakeCrt ( DbMaprMgr mgr , DbMaprItm mapr ) {
Criteria rv = null , cur = null ;
List_adp list = GetIdxFlds ( mgr , mapr ) ;
for ( Object kvObj : list ) {
KeyVal kv = ( KeyVal ) kvObj ;
cur = Db_crt_ . New_eq ( kv . Key ( ) , kv . Val ( ) ) ;
rv = ( rv = = null ) ? cur : Criteria_ . And ( rv , cur ) ;
}
return rv ;
}
List_adp GetIdxFlds ( DbMaprMgr mgr , DbMaprItm curMapr ) {
List_adp rv = List_adp_ . new_ ( ) ;
int maprStackCount = mgr . MaprStack ( ) . Count ( ) - 0 ; // -1 b/c current is added to stack
for ( int i = 0 ; i < maprStackCount ; i + + ) {
DbMaprItm mapr = ( DbMaprItm ) mgr . MaprStack ( ) . Get_at ( i ) ;
SrlObj gobj = ( SrlObj ) mgr . OwnerStack ( ) . Get_at ( i ) ;
for ( Object argObj : mapr . ContextFlds ( ) ) {
DbMaprArg arg = ( DbMaprArg ) argObj ;
Object propVal = GfoInvkAble_ . InvkCmd ( ( GfoInvkAble ) gobj , arg . ObjProp ( ) ) ;
rv . Add ( KeyVal_ . new_ ( arg . DbFld ( ) , propVal ) ) ;
}
}
for ( Object argObj : curMapr . ConstantFlds ( ) ) {
KeyVal arg = ( KeyVal ) argObj ;
rv . Add ( arg ) ;
}
return rv ;
}
GfoNde GetTbl ( DbMaprItm mapr , Criteria crit ) {
String key = mapr . TableName ( ) ;
GfoNde tblByRootCrt = GfoNde_ . as_ ( tables . Get_by ( key ) ) ;
if ( tblByRootCrt = = null ) {
DataRdr dbRdr = null ;
try {
dbRdr = conn . Exec_qry_as_old_rdr ( Db_qry_ . select_ ( ) . From_ ( mapr . TableName ( ) ) . Where_ ( rootCrt ) ) ;
tblByRootCrt = GfoNde_ . rdr_ ( dbRdr ) ;
}
finally { dbRdr . Rls ( ) ; }
tables . Add ( key , tblByRootCrt ) ;
}
GfoNde rv = GfoNde_ . tbl_ ( mapr . TableName ( ) , tblByRootCrt . Flds ( ) ) ;
for ( int i = 0 ; i < tblByRootCrt . Subs ( ) . Count ( ) ; i + + ) {
GfoNde row = tblByRootCrt . Subs ( ) . FetchAt_asGfoNde ( i ) ;
if ( crit . Matches ( row ) ) rv . Subs ( ) . Add ( row ) ;
}
return rv ;
}
void RowStack_add ( GfoNde tbl , int i ) {
GfoNdeList ndeList = tbl . Subs ( ) ; if ( i > = ndeList . Count ( ) ) throw Err_ . new_missing_idx ( i , ndeList . Count ( ) ) ;
rowStack . Add ( tbl . Subs ( ) . FetchAt_asGfoNde ( i ) ) ;
}
@Override public Object Read ( String key ) {
DbMaprItm mapr = ( DbMaprItm ) mgr . MaprStack ( ) . Get_at_last ( ) ;
GfoNde row = ( GfoNde ) rowStack . Get_at_last ( ) ;
DbMaprArg arg = mapr . Flds_get ( key ) ;
Object dbVal = null ; try { dbVal = row . Read ( arg . DbFld ( ) ) ; } catch ( Exception e ) { throw Err_ . new_exc ( e , "db" , "failed to read dbVal from row" , "key" , key , "fld" , arg . DbFld ( ) ) ; }
return dbVal ;
}
@Override public DataRdr Subs_byName_moveFirst ( String name ) { throw Err_ . new_unimplemented ( ) ; }
@Override public DataRdr Subs ( ) { throw Err_ . new_unimplemented ( ) ; }
@Override public int FieldCount ( ) { throw Err_ . new_unimplemented ( ) ; }
@Override public String KeyAt ( int i ) { throw Err_ . new_unimplemented ( ) ; }
@Override public Object ReadAt ( int i ) { throw Err_ . new_unimplemented ( ) ; }
@Override public KeyVal KeyValAt ( int i ) { throw Err_ . new_unimplemented ( ) ; }
@Override public SrlMgr SrlMgr_new ( Object o ) { return new DbMaprRdr ( ) ; }
Hash_adp tables = Hash_adp_ . new_ ( ) ;
Db_conn conn ; Criteria rootCrt ;
DbMaprMgr mgr ; List_adp rowStack = List_adp_ . new_ ( ) ;
public static DbMaprRdr new_ ( Db_conn_info dbInfo , Criteria rootCrt ) {
DbMaprRdr rv = new DbMaprRdr ( ) ;
rv . conn = Db_conn_pool . Instance . Get_or_new ( dbInfo ) ; rv . rootCrt = rootCrt ;
return rv ;
} DbMaprRdr ( ) { }
}