001    package railo.runtime.db;
002    
003    
004    import java.sql.Connection;
005    import java.sql.SQLException;
006    
007    import railo.runtime.PageContext;
008    import railo.runtime.PageContextImpl;
009    import railo.runtime.config.ConfigImpl;
010    import railo.runtime.engine.ThreadLocalPageContext;
011    import railo.runtime.exp.DatabaseException;
012    import railo.runtime.exp.DeprecatedException;
013    import railo.runtime.exp.ExceptionHandler;
014    import railo.runtime.exp.PageException;
015    import railo.runtime.exp.PageRuntimeException;
016    import railo.runtime.orm.ORMDatasourceConnection;
017    import railo.runtime.orm.ORMSession;
018    
019    /**
020     * this class handle multible db connection, transaction and logging
021     */
022    public final class DatasourceManagerImpl implements DataSourceManager {
023            
024            private ConfigImpl config;
025            
026            boolean autoCommit=true;
027            private int isolation=Connection.TRANSACTION_NONE;
028            private DatasourceConnection transConn;
029        
030    
031            /**
032             * constructor of the class
033             * @param pc
034             */
035            public DatasourceManagerImpl(ConfigImpl c) {
036                    this.config=c;
037            }
038    
039            @Override
040            public DatasourceConnection getConnection(PageContext pc,String _datasource, String user, String pass) throws PageException {
041                    return getConnection(pc,((PageContextImpl)pc).getDataSource(_datasource), user, pass);
042            }
043    
044            @Override
045            public DatasourceConnection getConnection(PageContext pc,DataSource ds, String user, String pass) throws PageException {
046                    if(autoCommit)
047                            return config.getDatasourceConnectionPool().getDatasourceConnection(pc,ds,user,pass);
048                    
049                    
050                    pc=ThreadLocalPageContext.get(pc);
051                    DatasourceConnection dc=((PageContextImpl)pc)._getConnection(ds,user,pass);
052                    
053                    // transaction
054                    //if(!autoCommit) {
055                try {
056                    if(transConn==null) {
057                            dc.getConnection().setAutoCommit(false);
058                                            
059                        if(isolation!=Connection.TRANSACTION_NONE)
060                                                dc.getConnection().setTransactionIsolation(isolation);
061                        transConn=dc;
062                            }
063                            else if(!transConn.equals(dc)) {
064                            if("_queryofquerydb".equalsIgnoreCase(ds.getName())) return dc;
065                                    throw new DatabaseException(
066                                                    "can't use different connections inside a transaction",null,null,dc);
067                            }
068                    else if(dc.getConnection().getAutoCommit()) {
069                        dc.getConnection().setAutoCommit(false);
070                    }
071                } catch (SQLException e) {
072                   ExceptionHandler.printStackTrace(e);
073                }
074                    //}
075                    return dc;
076            }
077            
078    
079            public void add(PageContext pc,ORMSession session) throws PageException {
080                    
081                    // transaction
082                    if(!autoCommit) {
083                try {
084                    if(transConn==null) {
085                            ORMDatasourceConnection dc=new ORMDatasourceConnection(pc,session);
086                            
087                        if(isolation!=Connection.TRANSACTION_NONE)
088                                                dc.getConnection().setTransactionIsolation(isolation);
089                        transConn=dc;
090                            }
091                            else if(!(transConn instanceof ORMDatasourceConnection)){
092                                    /*if(transConn.getDatasource().equals(session.getEngine().getDataSource())){
093                                            ORMDatasourceConnection dc=new ORMDatasourceConnection(pc,session);
094                            
095                            if(isolation!=Connection.TRANSACTION_NONE)
096                                                dc.getConnection().setTransactionIsolation(isolation);
097                            transConn=dc;
098                                    }
099                                    else*/
100                                            throw new DatabaseException(
101                                                    "can't use transaction for datasource and orm at the same time",null,null,null);
102                            }
103                } catch (SQLException e) {
104                   ExceptionHandler.printStackTrace(e);
105                }
106                    }
107            }
108            
109            @Override
110            public void releaseConnection(PageContext pc,DatasourceConnection dc) {
111                    if(autoCommit) config.getDatasourceConnectionPool().releaseDatasourceConnection(dc);
112            }
113            
114            /*private void releaseConnection(int pid,DatasourceConnection dc) {
115                    config.getDatasourceConnectionPool().releaseDatasourceConnection(pid,dc);
116            }*/
117            
118            @Override
119            public void begin() {
120                    this.autoCommit=false;
121                    this.isolation=Connection.TRANSACTION_NONE;             
122            }
123            
124            @Override
125            public void begin(String isolation) {
126                    this.autoCommit=false;
127            
128                    if(isolation.equalsIgnoreCase("read_uncommitted"))
129                        this.isolation=Connection.TRANSACTION_READ_UNCOMMITTED;
130                    else if(isolation.equalsIgnoreCase("read_committed"))
131                        this.isolation=Connection.TRANSACTION_READ_COMMITTED;
132                    else if(isolation.equalsIgnoreCase("repeatable_read"))
133                        this.isolation=Connection.TRANSACTION_REPEATABLE_READ;
134                    else if(isolation.equalsIgnoreCase("serializable"))
135                        this.isolation=Connection.TRANSACTION_SERIALIZABLE;
136                    else 
137                        this.isolation=Connection.TRANSACTION_NONE;
138            
139            }
140        @Override
141        public void begin(int isolation) {
142            //print.out("begin:"+autoCommit);
143            this.autoCommit=false;
144            this.isolation=isolation;
145        }
146    
147            @Override
148            public void rollback() throws DatabaseException {
149                    if(autoCommit)return;
150            //autoCommit=true;
151                    if(transConn!=null) {
152                            try {
153                                    transConn.getConnection().rollback();
154                                    //transConn.setAutoCommit(true);
155                            } 
156                            catch (SQLException e) {
157                                    throw new DatabaseException(e,transConn);
158                            }
159                            //transConn=null;
160                    }
161            }
162            
163            @Override
164            public void savepoint() throws DatabaseException {
165                    if(autoCommit)return;
166            //autoCommit=true;
167                    if(transConn!=null) {
168                            try {
169                                    transConn.getConnection().setSavepoint();
170                            } 
171                            catch (SQLException e) {
172                                    throw new DatabaseException(e,transConn);
173                            }
174                    }
175            }
176    
177            @Override
178            public void commit() throws DatabaseException {
179            //print.out("commit:"+autoCommit);
180            if(autoCommit)return ;
181            //autoCommit=true;
182                    if(transConn!=null) {
183                            try {
184                                    transConn.getConnection().commit();
185                                    //transConn.setAutoCommit(true);
186                            } 
187                            catch (SQLException e) {
188                                    throw new DatabaseException(e,transConn);
189                            }
190                            //transConn=null;
191                    }
192            }
193            
194        @Override
195        public boolean isAutoCommit() {
196            return autoCommit;
197        }
198    
199        @Override
200        public void end() {
201            autoCommit=true;
202            if(transConn!=null) {
203                    try {
204                    transConn.getConnection().setAutoCommit(true);
205                } 
206                catch (SQLException e) {
207                    ExceptionHandler.printStackTrace(e);
208                }
209                transConn=null;
210            }
211        }
212    
213            public void remove(DataSource datasource) {
214                    config.getDatasourceConnectionPool().remove(datasource);
215            }
216    
217            public void remove(String datasource) {
218                    throw new PageRuntimeException(new DeprecatedException("method no longer supported!"));
219                    //config.getDatasourceConnectionPool().remove(datasource);
220            }
221    
222            public void release() {
223                    this.transConn=null;
224                    this.isolation=Connection.TRANSACTION_NONE;
225            }
226    
227    }