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 DatasourceConnection {
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        @Override
047        public Connection getConnection() {
048            return connection;
049        }
050    
051        @Override
052        public DataSource getDatasource() {
053            return datasource;
054        }
055    
056        @Override
057        public boolean isTimeout() {
058            int timeout=datasource.getConnectionTimeout();
059            if(timeout<1)timeout=1;
060            timeout*=60000;      
061            return (time+timeout)<System.currentTimeMillis();
062        }
063    
064            public DatasourceConnection using() {
065                    time=System.currentTimeMillis();
066                    return this;
067            }
068    
069            /**
070             * @return the password
071             */
072            public String getPassword() {
073                    return password;
074            }
075    
076            /**
077             * @return the username
078             */
079            public String getUsername() {
080                    return username;
081            }
082    
083            @Override
084            public boolean equals(Object obj) {
085                    if(this==obj) return true;
086                    
087                    if(!(obj instanceof DatasourceConnectionImpl)) return false;
088                    return equals(this, (DatasourceConnection) obj);
089                    
090                    
091                    /*if(!(obj instanceof DatasourceConnectionImpl)) return false;
092                    DatasourceConnectionImpl other=(DatasourceConnectionImpl) obj;
093                    
094                    if(!datasource.equals(other.datasource)) return false;
095                    //print.out(username+".equals("+other.username+") && "+password+".equals("+other.password+")");
096                    return username.equals(other.username) && password.equals(other.password);*/
097            }
098            
099            public static boolean equals(DatasourceConnection left,DatasourceConnection right) {
100                    
101                    if(!left.getDatasource().equals(right.getDatasource())) return false;
102                    return left.getUsername().equals(right.getUsername()) && left.getPassword().equals(right.getPassword());
103                    
104            }
105            
106            
107    
108            /**
109             * @return the transactionIsolationLevel
110             */
111            public int getTransactionIsolationLevel() {
112                    return transactionIsolationLevel;
113            }
114    
115            
116            public int getRequestId() {
117                    return requestId;
118            }
119            public void setRequestId(int requestId) {
120                    this.requestId=requestId;
121            }
122    
123            @Override
124            public boolean supportsGetGeneratedKeys() {
125                    if(supportsGetGeneratedKeys==null){
126                            try {
127                                    supportsGetGeneratedKeys=Caster.toBoolean(getConnection().getMetaData().supportsGetGeneratedKeys());
128                            } catch (Throwable t) {
129                                    return false;
130                            }
131                    }
132                    return supportsGetGeneratedKeys.booleanValue();
133            }
134            
135            //private Map<String,PreparedStatement> preparedStatements=new HashMap<String, PreparedStatement>();
136            
137            @Override
138            public PreparedStatement getPreparedStatement(SQL sql, boolean createGeneratedKeys,boolean allowCaching) throws SQLException {
139                    if(createGeneratedKeys) return getConnection().prepareStatement(sql.getSQLString(),Statement.RETURN_GENERATED_KEYS);
140                    return getConnection().prepareStatement(sql.getSQLString());
141            }
142            
143            
144            /*public PreparedStatement getPreparedStatement(SQL sql, boolean createGeneratedKeys,boolean allowCaching) throws SQLException {
145                    // create key
146                    String strSQL=sql.getSQLString();
147                    String key=strSQL.trim()+":"+createGeneratedKeys;
148                    try {
149                            key = MD5.getDigestAsString(key);
150                    } catch (IOException e) {}
151                    PreparedStatement ps = allowCaching?preparedStatements.get(key):null;
152                    if(ps!=null) {
153                            if(DataSourceUtil.isClosed(ps,true)) 
154                                    preparedStatements.remove(key);
155                            else return ps;
156                    }
157                    
158                    
159                    if(createGeneratedKeys) ps= getConnection().prepareStatement(strSQL,Statement.RETURN_GENERATED_KEYS);
160                    else ps=getConnection().prepareStatement(strSQL);
161                    if(preparedStatements.size()>MAX_PS)
162                            closePreparedStatements((preparedStatements.size()-MAX_PS)+1);
163                    if(allowCaching)preparedStatements.put(key,ps);
164                    return ps;
165            }*/
166            
167            
168    
169            @Override
170            public PreparedStatement getPreparedStatement(SQL sql, int resultSetType,int resultSetConcurrency) throws SQLException {
171                    return getConnection().prepareStatement(sql.getSQLString(),resultSetType,resultSetConcurrency);
172            }
173            
174            /*
175             
176            public PreparedStatement getPreparedStatement(SQL sql, int resultSetType,int resultSetConcurrency) throws SQLException {
177                    boolean allowCaching=false;
178                    // create key
179                    String strSQL=sql.getSQLString();
180                    String key=strSQL.trim()+":"+resultSetType+":"+resultSetConcurrency;
181                    try {
182                            key = MD5.getDigestAsString(key);
183                    } catch (IOException e) {}
184                    PreparedStatement ps = allowCaching?preparedStatements.get(key):null;
185                    if(ps!=null) {
186                            if(DataSourceUtil.isClosed(ps,true)) 
187                                    preparedStatements.remove(key);
188                            else return ps;
189                    }
190                    
191                    ps=getConnection().prepareStatement(strSQL,resultSetType,resultSetConcurrency);
192                    if(preparedStatements.size()>MAX_PS)
193                            closePreparedStatements((preparedStatements.size()-MAX_PS)+1);
194                    if(allowCaching)preparedStatements.put(key,ps);
195                    return ps;
196            }
197             */
198            
199    
200            @Override
201            public void close() throws SQLException {
202                    //closePreparedStatements(-1);
203                    getConnection().close();
204            }
205            
206    
207            /*public void closePreparedStatements(int maxDelete) throws SQLException {
208                    Iterator<Entry<String, PreparedStatement>> it = preparedStatements.entrySet().iterator();
209                    int count=0;
210                    while(it.hasNext()){
211                            try {
212                                    Entry<String, PreparedStatement> entry = it.next();
213                                    entry.getValue().close();
214                                    it.remove();
215                                    if(maxDelete!=0 && ++count>=maxDelete) break;
216                            } 
217                            catch (SQLException e) {}
218                    }
219                    
220            }*/
221            
222            
223            /*protected void finalize() throws Throwable {
224                try {
225                    close();        // close open files
226                } finally {
227                    super.finalize();
228                }
229            }*/
230    }