001    package railo.runtime.db;
002    
003    import java.sql.Connection;
004    import java.sql.PreparedStatement;
005    import java.sql.SQLException;
006    import java.sql.Statement;
007    
008    import railo.runtime.op.Caster;
009    
010    /**
011     * wrap for datasorce and connection from it
012     */
013    public final class DatasourceConnectionImpl implements DatasourceConnectionPro {
014        
015        //private static final int MAX_PS = 100;
016            private Connection connection;
017        private DataSource datasource;
018        private long time;
019            private String username;
020            private String password;
021            private int transactionIsolationLevel=-1;
022            private int requestId=-1;
023            private Boolean supportsGetGeneratedKeys;
024    
025        /**
026         * @param connection
027         * @param datasource
028         * @param pass  
029         * @param user 
030         */
031        public DatasourceConnectionImpl(Connection connection, DataSource datasource, String username, String password) {
032            this.connection = connection;
033            this.datasource = datasource;
034            this.time=System.currentTimeMillis();
035            this.username = username;
036            this.password = password;
037            
038            if(username==null) {
039                    this.username=datasource.getUsername();
040                    this.password=datasource.getPassword();
041            }
042            if(this.password==null)this.password="";
043                    
044        }
045        
046        /**
047         * @see railo.runtime.db.DatasourceConnection#getConnection()
048         */
049        public Connection getConnection() {
050            return connection;
051        }
052    
053        /**
054         * @see railo.runtime.db.DatasourceConnection#getDatasource()
055         */
056        public DataSource getDatasource() {
057            return datasource;
058        }
059    
060        /**
061         * @see railo.runtime.db.DatasourceConnection#isTimeout()
062         */
063        public boolean isTimeout() {
064            int timeout=datasource.getConnectionTimeout();
065            if(timeout<1)timeout=1;
066            timeout*=60000;      
067            return (time+timeout)<System.currentTimeMillis();
068        }
069    
070            public DatasourceConnection using() {
071                    time=System.currentTimeMillis();
072                    return this;
073            }
074    
075            /**
076             * @return the password
077             */
078            public String getPassword() {
079                    return password;
080            }
081    
082            /**
083             * @return the username
084             */
085            public String getUsername() {
086                    return username;
087            }
088    
089            /**
090             *
091             * @see java.lang.Object#equals(java.lang.Object)
092             */
093            public boolean equals(Object obj) {
094                    if(this==obj) return true;
095                    
096                    if(!(obj instanceof DatasourceConnectionImpl)) return false;
097                    return equals(this, (DatasourceConnection) obj);
098                    
099                    
100                    /*if(!(obj instanceof DatasourceConnectionImpl)) return false;
101                    DatasourceConnectionImpl other=(DatasourceConnectionImpl) obj;
102                    
103                    if(!datasource.equals(other.datasource)) return false;
104                    //print.out(username+".equals("+other.username+") && "+password+".equals("+other.password+")");
105                    return username.equals(other.username) && password.equals(other.password);*/
106            }
107            
108            public static boolean equals(DatasourceConnection left,DatasourceConnection right) {
109                    
110                    if(!left.getDatasource().equals(right.getDatasource())) return false;
111                    return left.getUsername().equals(right.getUsername()) && left.getPassword().equals(right.getPassword());
112                    
113            }
114            
115            
116    
117            /**
118             * @return the transactionIsolationLevel
119             */
120            public int getTransactionIsolationLevel() {
121                    return transactionIsolationLevel;
122            }
123    
124            
125            public int getRequestId() {
126                    return requestId;
127            }
128            public void setRequestId(int requestId) {
129                    this.requestId=requestId;
130            }
131    
132            /**
133             * @see railo.runtime.db.DatasourceConnectionPro#supportsGetGeneratedKeys()
134             */
135            public boolean supportsGetGeneratedKeys() {
136                    if(supportsGetGeneratedKeys==null){
137                            try {
138                                    supportsGetGeneratedKeys=Caster.toBoolean(getConnection().getMetaData().supportsGetGeneratedKeys());
139                            } catch (Throwable t) {
140                                    return false;
141                            }
142                    }
143                    return supportsGetGeneratedKeys.booleanValue();
144            }
145            
146            //private Map<String,PreparedStatement> preparedStatements=new HashMap<String, PreparedStatement>();
147            
148            /**
149             * @see railo.runtime.db.DatasourceConnectionPro#getPreparedStatement(railo.runtime.db.SQL, boolean)
150             */
151            public PreparedStatement getPreparedStatement(SQL sql, boolean createGeneratedKeys,boolean allowCaching) throws SQLException {
152                    if(createGeneratedKeys) return getConnection().prepareStatement(sql.getSQLString(),Statement.RETURN_GENERATED_KEYS);
153                    return getConnection().prepareStatement(sql.getSQLString());
154            }
155            
156            
157            /*public PreparedStatement getPreparedStatement(SQL sql, boolean createGeneratedKeys,boolean allowCaching) throws SQLException {
158                    // create key
159                    String strSQL=sql.getSQLString();
160                    String key=strSQL.trim()+":"+createGeneratedKeys;
161                    try {
162                            key = MD5.getDigestAsString(key);
163                    } catch (IOException e) {}
164                    PreparedStatement ps = allowCaching?preparedStatements.get(key):null;
165                    if(ps!=null) {
166                            if(DataSourceUtil.isClosed(ps,true)) 
167                                    preparedStatements.remove(key);
168                            else return ps;
169                    }
170                    
171                    
172                    if(createGeneratedKeys) ps= getConnection().prepareStatement(strSQL,Statement.RETURN_GENERATED_KEYS);
173                    else ps=getConnection().prepareStatement(strSQL);
174                    if(preparedStatements.size()>MAX_PS)
175                            closePreparedStatements((preparedStatements.size()-MAX_PS)+1);
176                    if(allowCaching)preparedStatements.put(key,ps);
177                    return ps;
178            }*/
179            
180            
181    
182            /**
183             * @see railo.runtime.db.DatasourceConnectionPro#getPreparedStatement(railo.runtime.db.SQL, boolean)
184             */
185            public PreparedStatement getPreparedStatement(SQL sql, int resultSetType,int resultSetConcurrency) throws SQLException {
186                    return getConnection().prepareStatement(sql.getSQLString(),resultSetType,resultSetConcurrency);
187            }
188            
189            /*
190             
191            public PreparedStatement getPreparedStatement(SQL sql, int resultSetType,int resultSetConcurrency) throws SQLException {
192                    boolean allowCaching=false;
193                    // create key
194                    String strSQL=sql.getSQLString();
195                    String key=strSQL.trim()+":"+resultSetType+":"+resultSetConcurrency;
196                    try {
197                            key = MD5.getDigestAsString(key);
198                    } catch (IOException e) {}
199                    PreparedStatement ps = allowCaching?preparedStatements.get(key):null;
200                    if(ps!=null) {
201                            if(DataSourceUtil.isClosed(ps,true)) 
202                                    preparedStatements.remove(key);
203                            else return ps;
204                    }
205                    
206                    ps=getConnection().prepareStatement(strSQL,resultSetType,resultSetConcurrency);
207                    if(preparedStatements.size()>MAX_PS)
208                            closePreparedStatements((preparedStatements.size()-MAX_PS)+1);
209                    if(allowCaching)preparedStatements.put(key,ps);
210                    return ps;
211            }
212             */
213            
214    
215            /**
216             * @see railo.runtime.db.DatasourceConnectionPro#close()
217             */
218            public void close() throws SQLException {
219                    //closePreparedStatements(-1);
220                    getConnection().close();
221            }
222            
223    
224            /*public void closePreparedStatements(int maxDelete) throws SQLException {
225                    Iterator<Entry<String, PreparedStatement>> it = preparedStatements.entrySet().iterator();
226                    int count=0;
227                    while(it.hasNext()){
228                            try {
229                                    Entry<String, PreparedStatement> entry = it.next();
230                                    entry.getValue().close();
231                                    it.remove();
232                                    if(maxDelete!=0 && ++count>=maxDelete) break;
233                            } 
234                            catch (SQLException e) {}
235                    }
236                    
237            }*/
238            
239            
240            /*protected void finalize() throws Throwable {
241                try {
242                    close();        // close open files
243                } finally {
244                    super.finalize();
245                }
246            }*/
247    }