001 package railo.runtime.type.scope.storage; 002 003 import java.sql.SQLException; 004 005 import railo.commons.io.log.Log; 006 import railo.runtime.PageContext; 007 import railo.runtime.PageContextImpl; 008 import railo.runtime.config.Config; 009 import railo.runtime.config.ConfigImpl; 010 import railo.runtime.db.DataSource; 011 import railo.runtime.db.DatasourceConnection; 012 import railo.runtime.db.DatasourceConnectionPool; 013 import railo.runtime.debug.DebuggerImpl; 014 import railo.runtime.debug.DebuggerPro; 015 import railo.runtime.engine.ThreadLocalPageContext; 016 import railo.runtime.exp.ApplicationException; 017 import railo.runtime.exp.PageException; 018 import railo.runtime.op.Caster; 019 import railo.runtime.type.Query; 020 import railo.runtime.type.Struct; 021 import railo.runtime.type.dt.DateTime; 022 import railo.runtime.type.dt.DateTimeImpl; 023 import railo.runtime.type.scope.ScopeContext; 024 import railo.runtime.type.scope.storage.db.SQLExecutionFactory; 025 import railo.runtime.type.scope.storage.db.SQLExecutor; 026 import railo.runtime.type.util.KeyConstants; 027 028 /** 029 * client scope that store it's data in a datasource 030 */ 031 public abstract class StorageScopeDatasource extends StorageScopeImpl { 032 033 private static final long serialVersionUID = 239179599401918216L; 034 035 public static final String PREFIX = "cf"; 036 037 private String datasourceName; 038 039 private String appName; 040 041 private String cfid; 042 043 044 /** 045 * Constructor of the class 046 * @param pc 047 * @param name 048 * @param sct 049 * @param b 050 */ 051 protected StorageScopeDatasource(PageContext pc,String datasourceName, String strType,int type,Struct sct) { 052 super( 053 sct, 054 doNowIfNull(pc,Caster.toDate(sct.get(TIMECREATED,null),false,pc.getTimeZone(),null)), 055 doNowIfNull(pc,Caster.toDate(sct.get(LASTVISIT,null),false,pc.getTimeZone(),null)), 056 -1, 057 type==SCOPE_CLIENT?Caster.toIntValue(sct.get(HITCOUNT,"1"),1):0, 058 strType,type); 059 060 this.datasourceName=datasourceName; 061 appName=pc.getApplicationContext().getName(); 062 cfid=pc.getCFID(); 063 } 064 065 /** 066 * Constructor of the class, clone existing 067 * @param other 068 */ 069 protected StorageScopeDatasource(StorageScopeDatasource other,boolean deepCopy) { 070 super(other,deepCopy); 071 this.datasourceName=other.datasourceName; 072 } 073 074 private static DateTime doNowIfNull(PageContext pc,DateTime dt) { 075 if(dt==null)return new DateTimeImpl(pc.getConfig()); 076 return dt; 077 } 078 079 080 081 082 protected static Struct _loadData(PageContext pc, String datasourceName,String strType,int type, Log log, boolean mxStyle) throws PageException { 083 ConfigImpl config = (ConfigImpl)pc.getConfig(); 084 DatasourceConnectionPool pool = config.getDatasourceConnectionPool(); 085 DatasourceConnection dc=pool.getDatasourceConnection(pc,((PageContextImpl)pc).getDataSource(datasourceName),null,null); 086 SQLExecutor executor=SQLExecutionFactory.getInstance(dc); 087 088 089 Query query; 090 091 try { 092 if(!dc.getDatasource().isStorage()) 093 throw new ApplicationException("storage usage for this datasource is disabled, you can enable this in the railo administrator."); 094 query = executor.select(pc.getConfig(),pc.getCFID(),pc.getApplicationContext().getName(), dc, type,log, true); 095 } 096 catch (SQLException se) { 097 throw Caster.toPageException(se); 098 } 099 finally { 100 if(dc!=null) pool.releaseDatasourceConnection(dc); 101 } 102 boolean debugUsage=DebuggerImpl.debugQueryUsage(pc,query); 103 104 if(query!=null) 105 ((DebuggerPro)pc.getDebugger()).addQuery(debugUsage?query:null,datasourceName,"",query.getSql(),query.getRecordcount(),pc.getCurrentPageSource(),query.getExecutionTime()); 106 boolean _isNew = query.getRecordcount()==0; 107 108 if(_isNew) { 109 ScopeContext.info(log,"create new "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID()+" in datasource ["+datasourceName+"]"); 110 return null; 111 } 112 String str=Caster.toString(query.get(KeyConstants._data)); 113 if(mxStyle) return null; 114 Struct s = (Struct)pc.evaluate(str); 115 ScopeContext.info(log,"load existing data from ["+datasourceName+"."+PREFIX+"_"+strType+"_data] to create "+strType+" scope for "+pc.getApplicationContext().getName()+"/"+pc.getCFID()); 116 117 return s; 118 } 119 120 @Override 121 public void touchAfterRequest(PageContext pc) { 122 setTimeSpan(pc); 123 super.touchAfterRequest(pc); 124 125 store(pc.getConfig()); 126 } 127 128 public void store(Config config) { 129 //if(!super.hasContent()) return; 130 131 DatasourceConnection dc = null; 132 ConfigImpl ci = (ConfigImpl)config; 133 DatasourceConnectionPool pool = ci.getDatasourceConnectionPool(); 134 Log log=((ConfigImpl)config).getScopeLogger(); 135 try { 136 PageContext pc = ThreadLocalPageContext.get();// FUTURE change method interface 137 DataSource ds; 138 if(pc!=null) ds=((PageContextImpl)pc).getDataSource(datasourceName); 139 else ds=config.getDataSource(datasourceName); 140 dc=pool.getDatasourceConnection(null,ds,null,null); 141 SQLExecutor executor=SQLExecutionFactory.getInstance(dc); 142 executor.update(config, cfid,appName, dc, getType(), sct,getTimeSpan(),log); 143 } 144 catch (Throwable t) { 145 ScopeContext.error(log, t); 146 } 147 finally { 148 if(dc!=null) pool.releaseDatasourceConnection(dc); 149 } 150 } 151 152 public void unstore(Config config) { 153 ConfigImpl ci=(ConfigImpl) config; 154 DatasourceConnection dc = null; 155 156 157 DatasourceConnectionPool pool = ci.getDatasourceConnectionPool(); 158 Log log=((ConfigImpl)config).getScopeLogger(); 159 try { 160 PageContext pc = ThreadLocalPageContext.get();// FUTURE change method interface 161 DataSource ds; 162 if(pc!=null) ds=((PageContextImpl)pc).getDataSource(datasourceName); 163 else ds=config.getDataSource(datasourceName); 164 dc=pool.getDatasourceConnection(null,ds,null,null); 165 SQLExecutor executor=SQLExecutionFactory.getInstance(dc); 166 executor.delete(config, cfid,appName, dc, getType(),log); 167 } 168 catch (Throwable t) { 169 ScopeContext.error(log, t); 170 } 171 finally { 172 if(dc!=null) pool.releaseDatasourceConnection(dc); 173 } 174 } 175 176 177 178 179 180 181 182 183 184 185 @Override 186 public void touchBeforeRequest(PageContext pc) { 187 setTimeSpan(pc); 188 super.touchBeforeRequest(pc); 189 } 190 191 @Override 192 public String getStorageType() { 193 return "Datasource"; 194 } 195 196 /** 197 * @return the datasourceName 198 */ 199 public String getDatasourceName() { 200 return datasourceName; 201 } 202 }