001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.db; 020 021import java.util.Iterator; 022import java.util.Map.Entry; 023import java.util.TimeZone; 024 025import lucee.commons.lang.ClassException; 026import lucee.commons.lang.StringUtil; 027import lucee.runtime.config.ConfigWebFactory; 028import lucee.runtime.op.Caster; 029import lucee.runtime.type.Collection.Key; 030import lucee.runtime.type.KeyImpl; 031import lucee.runtime.type.Struct; 032import lucee.runtime.type.util.CollectionUtil; 033 034 035/** 036 * 037 */ 038public final class DataSourceImpl extends DataSourceSupport { 039 040 private String connStr; 041 private String host; 042 private String database; 043 private int port; 044 private String connStrTranslated; 045 private Struct custom; 046 private boolean validate; 047 private String dbdriver; 048 private final boolean literalTimestampWithTSOffset; 049 050 /** 051 * constructor of the class 052 * @param name 053 * @param className 054 * @param host 055 * @param dsn 056 * @param database 057 * @param port 058 * @param username 059 * @param password 060 * @param connectionLimit 061 * @param connectionTimeout 062 * @param blob 063 * @param clob 064 * @param allow 065 * @param custom 066 * @param readOnly 067 * @throws ClassException 068 */ 069 public DataSourceImpl(String name,String className, String host, String dsn, String database, int port, String username, String password, 070 int connectionLimit, int connectionTimeout,long metaCacheTimeout, boolean blob, boolean clob, int allow, Struct custom, boolean readOnly, 071 boolean validate, boolean storage, TimeZone timezone, String dbdriver, boolean literalTimestampWithTSOffset) throws ClassException { 072 073 this(name, toClass(className), host, dsn, database, port, username, password, connectionLimit, connectionTimeout,metaCacheTimeout, blob, clob, allow, custom, readOnly, validate, storage, timezone, dbdriver,literalTimestampWithTSOffset); 074 } 075 076 private DataSourceImpl(String name, Class<?> clazz, String host, String dsn, String database, int port, String username, String password, 077 int connectionLimit, int connectionTimeout, long metaCacheTimeout, boolean blob, boolean clob, int allow, Struct custom, boolean readOnly, 078 boolean validate, boolean storage, TimeZone timezone, String dbdriver, boolean literalTimestampWithTSOffset) { 079 080 super(name, clazz,username,ConfigWebFactory.decrypt(password),blob,clob,connectionLimit, connectionTimeout, metaCacheTimeout, timezone, allow<0?ALLOW_ALL:allow, storage, readOnly); 081 082 this.host=host; 083 this.database=database; 084 this.connStr=dsn; 085 this.port=port; 086 087 this.custom=custom; 088 this.validate=validate; 089 090 this.connStrTranslated=dsn; 091 translateDsn(); 092 093 this.dbdriver = dbdriver; 094 this.literalTimestampWithTSOffset=literalTimestampWithTSOffset; 095 096 // throw new DatabaseException("can't find class ["+classname+"] for jdbc driver, check if driver (jar file) is inside lib folder",e.getMessage(),null,null,null); 097 098 } 099 private void translateDsn() { 100 connStrTranslated=replace(connStrTranslated,"host",host,false); 101 connStrTranslated=replace(connStrTranslated,"database",database,false); 102 connStrTranslated=replace(connStrTranslated,"port",Caster.toString(port),false); 103 connStrTranslated=replace(connStrTranslated,"username",getUsername(),false); 104 connStrTranslated=replace(connStrTranslated,"password",getPassword(),false); 105 106 //Collection.Key[] keys = custom==null?new Collection.Key[0]:custom.keys(); 107 if(custom!=null) { 108 Iterator<Entry<Key, Object>> it = custom.entryIterator(); 109 Entry<Key, Object> e; 110 while(it.hasNext()) { 111 e = it.next(); 112 connStrTranslated=replace(connStrTranslated,e.getKey().getString(),Caster.toString(e.getValue(),""),true); 113 } 114 } 115 } 116 117 private String replace(String src, String name, String value,boolean doQueryString) { 118 if(StringUtil.indexOfIgnoreCase(src,"{"+name+"}")!=-1) { 119 return StringUtil.replace(connStrTranslated,"{"+name+"}",value,false); 120 } 121 if(!doQueryString) return src; 122 if(getClazz().getName().indexOf("microsoft")!=-1 || getClazz().getName().indexOf("jtds")!=-1) 123 return src+=';'+name+'='+value; 124 else if(getClazz().getName().indexOf("teradata")!=-1) 125 return src+='/'+name+'='+value; 126 return src+=((src.indexOf('?')!=-1)?'&':'?')+name+'='+value; 127 } 128 129 @Override 130 public String getDsnOriginal() { 131 return getConnectionString(); 132 } 133 134 @Override 135 public String getConnectionString() { 136 return connStr; 137 } 138 139 @Override 140 public String getDsnTranslated() { 141 return getConnectionStringTranslated(); 142 } 143 144 @Override 145 public String getConnectionStringTranslated() { 146 return connStrTranslated; 147 } 148 149 @Override 150 public String getDatabase() { 151 return database; 152 } 153 154 @Override 155 public int getPort() { 156 return port; 157 } 158 159 @Override 160 public String getHost() { 161 return host; 162 } 163 164 @Override 165 public Object clone() { 166 return new DataSourceImpl(getName(),getClazz(), host, connStr, database, port, getUsername(), getPassword(), getConnectionLimit(), getConnectionTimeout(),getMetaCacheTimeout(), isBlob(), isClob(), allow, custom, isReadOnly(),validate,isStorage(),getTimeZone(), dbdriver,literalTimestampWithTSOffset); 167 } 168 169 @Override 170 public DataSource cloneReadOnly() { 171 return new DataSourceImpl(getName(),getClazz(), host, connStr, database, port, getUsername(), getPassword(), getConnectionLimit(), getConnectionTimeout(),getMetaCacheTimeout(), isBlob(), isClob(), allow,custom, true,validate,isStorage(),getTimeZone(), dbdriver,literalTimestampWithTSOffset); 172 } 173 174 @Override 175 public String getCustomValue(String key) { 176 return Caster.toString(custom.get(KeyImpl.init(key),null),""); 177 } 178 179 @Override 180 public String[] getCustomNames() { 181 return CollectionUtil.keysAsString(custom); 182 } 183 184 @Override 185 public Struct getCustoms() { 186 return (Struct)custom.clone(); 187 } 188 189 public boolean getLiteralTimestampWithTSOffset() { 190 return literalTimestampWithTSOffset; 191 } 192 193 @Override 194 public boolean validate() { 195 return validate; 196 } 197 198 public String getDbDriver() { 199 return dbdriver; 200 } 201}