root / trunk / libraries / libGDBMS / src / com / hardcode / gdbms / engine / data / DataSourceFactory.java @ 466
History | View | Annotate | Download (12.4 KB)
1 |
package com.hardcode.gdbms.engine.data; |
---|---|
2 |
|
3 |
import com.hardcode.driverManager.Driver; |
4 |
import com.hardcode.driverManager.DriverLoadException; |
5 |
import com.hardcode.driverManager.DriverManager; |
6 |
|
7 |
import com.hardcode.gdbms.engine.Strategy; |
8 |
import com.hardcode.gdbms.engine.StrategyManager; |
9 |
import com.hardcode.gdbms.engine.instruction.Adapter; |
10 |
import com.hardcode.gdbms.engine.instruction.SelectAdapter; |
11 |
import com.hardcode.gdbms.engine.instruction.SemanticException; |
12 |
import com.hardcode.gdbms.engine.instruction.TableRefAdapter; |
13 |
import com.hardcode.gdbms.engine.instruction.UnionAdapter; |
14 |
import com.hardcode.gdbms.engine.instruction.Utilities; |
15 |
import com.hardcode.gdbms.parser.SimpleNode; |
16 |
|
17 |
import java.io.File; |
18 |
import java.io.IOException; |
19 |
|
20 |
import java.util.HashMap; |
21 |
|
22 |
|
23 |
/* Generated by Together */
|
24 |
public class DataSourceFactory { |
25 |
/**
|
26 |
* Asocia los nombres de las tablas con la informaci?n del origen de datos
|
27 |
*/
|
28 |
private static HashMap tableSource = new HashMap(); |
29 |
|
30 |
/**
|
31 |
* Asocia los nombres de los or?genes de datos de base de datos con el
|
32 |
* nombre de la tabla en el sistema de gesti?n original
|
33 |
*/
|
34 |
private static HashMap nameTable = new HashMap(); |
35 |
private static DriverManager dm; |
36 |
|
37 |
static {
|
38 |
//Setup de las tablas
|
39 |
|
40 |
/* addFileDataSource("csv", "persona", "persona.csv", "persona.csv");
|
41 |
addFileDataSource("csv", "coche", "coche.csv", "coche.csv");
|
42 |
addFileDataSource("gdbms dbf driver", "vias", "vias.dbf", "vias.dbf");
|
43 |
addFileDataSource("gdbms dbf driver", "ejes", "ejes.dbf", "ejes.dbf");
|
44 |
addDBDataSource("mysql", "jdbc:mysql://localhost/prueba?user=root",
|
45 |
"prueba", "localhost/prueba", "mysql");
|
46 |
*/
|
47 |
} |
48 |
|
49 |
/**
|
50 |
* A?ade un origen de datos de fichero al sistema
|
51 |
*
|
52 |
* @param driverName DOCUMENT ME!
|
53 |
* @param name Nombre de la tabla con el que se har? referencia en las
|
54 |
* instrucciones
|
55 |
* @param file Fichero con los datos
|
56 |
* @param dbms Sistema de base de datos capaz de ejecutar instrucciones SQL
|
57 |
* en el que reside el origen de datos. Este par?metro se utiliza
|
58 |
* para delegar las instrucciones SQL en dicho sistema, cuando las
|
59 |
* tablas que intervienen en una instrucci?n est?n todas en el
|
60 |
* mismo dbms. Generalmente los ficheros no residen en ning?n dbms,
|
61 |
* por lo que habr? que asignarle un valor distinto a cada
|
62 |
* DataSource. El nombre del fichero suele ser una buena opci?n
|
63 |
*/
|
64 |
public static void addFileDataSource(String driverName, String name, |
65 |
String file, String dbms) { |
66 |
FileDriverInfo info = new FileDriverInfo();
|
67 |
info.name = name; |
68 |
info.dbms = dbms; |
69 |
info.file = file; |
70 |
info.driverName = driverName; |
71 |
tableSource.put(name, info); |
72 |
} |
73 |
|
74 |
/**
|
75 |
* A?ade un origen de datos de base de datos al sistema
|
76 |
*
|
77 |
* @param name Nombre de la tabla con el que se har? referencia en las
|
78 |
* instrucciones
|
79 |
* @param host Cadena de conexi?n para conectar con el sgbd donde se
|
80 |
* encuentra la tabla
|
81 |
* @param port Nombre del sgbd capaz de ejecutar SQL en el que reside la
|
82 |
* tabla. Generalmente ser? la parte de la cadena de conexi?n
|
83 |
* correspondiente a host, puerto y nombre de la base de datos
|
84 |
* @param user Nombre de usuario. Null para acceso sin usuario
|
85 |
* @param password Si el usuario es null se ignora el password
|
86 |
* @param dbName Nombre de la base de datos a la que se accede
|
87 |
* @param tableName Nombre de la tabla en el sgbd original
|
88 |
* @param driverInfo Informaci?n para saber qu? driver debe acceder a la
|
89 |
* informaci?n. Se escoger? el driver cuyo valor de retorno del
|
90 |
* m?todo getType coincida con este valor
|
91 |
*/
|
92 |
public static void addDBDataSource(String name, String host, int port, |
93 |
String user, String password, String dbName, String tableName, |
94 |
String driverInfo) {
|
95 |
DBDriverInfo info = new DBDriverInfo();
|
96 |
info.name = name; |
97 |
info.host = host; |
98 |
info.port = port; |
99 |
info.user = user; |
100 |
info.password = password; |
101 |
info.dbName = dbName; |
102 |
info.dbms = host + ":" + port + "/" + dbName; |
103 |
info.sqlQuery = tableName; |
104 |
info.driverInfo = driverInfo; |
105 |
tableSource.put(name, info); |
106 |
nameTable.put(name, tableName); |
107 |
} |
108 |
|
109 |
/**
|
110 |
* Dado el nombre de una tabla, se busca el fichero asociado a dicha tabla
|
111 |
* y se obtiene un datasource adecuado en funcion del tipo del fichero
|
112 |
* accediendo al subsistema de drivers
|
113 |
*
|
114 |
* @param tableName Nombre de la tabla
|
115 |
*
|
116 |
* @return DataSource que accede a dicha tabla
|
117 |
*
|
118 |
* @throws NoSuchTableException
|
119 |
* @throws DriverLoadException
|
120 |
* @throws RuntimeException Si se encuentra un adaptador no contemplado
|
121 |
* (bug)
|
122 |
*/
|
123 |
public static DataSource createRandomDataSource(String tableName) |
124 |
throws NoSuchTableException, DriverLoadException {
|
125 |
DriverInfo info = (DriverInfo) tableSource.get(tableName); |
126 |
|
127 |
if (info == null) { |
128 |
throw new NoSuchTableException(tableName); |
129 |
} |
130 |
|
131 |
if (info instanceof FileDriverInfo) { |
132 |
FileDriverInfo fileInfo = (FileDriverInfo) info; |
133 |
|
134 |
Driver d = dm.getDriver(fileInfo.driverName);
|
135 |
|
136 |
FileDataSourceAdapter adapter = new FileDataSourceAdapter();
|
137 |
adapter.setDriver((FileDriver) d); |
138 |
adapter.setFile(new File(fileInfo.file)); |
139 |
adapter.setName(tableName); |
140 |
adapter.setDBMS(fileInfo.dbms); |
141 |
|
142 |
return adapter;
|
143 |
} else if (info instanceof DBDriverInfo) { |
144 |
DBDriverInfo dbInfo = (DBDriverInfo) info; |
145 |
|
146 |
String driverInfo = dbInfo.driverInfo;
|
147 |
Driver d = dm.getDriver(driverInfo);
|
148 |
|
149 |
DBTableDataSourceAdapter adapter = new DBTableDataSourceAdapter();
|
150 |
adapter.setDriver((DBDriver) d); |
151 |
adapter.setConnectionString(dbInfo.host, dbInfo.port, dbInfo.dbName, dbInfo.user, dbInfo.password); |
152 |
adapter.setTable(dbInfo.sqlQuery); |
153 |
adapter.setName(tableName); |
154 |
adapter.setDBMS(dbInfo.dbms); |
155 |
|
156 |
return adapter;
|
157 |
} else {
|
158 |
throw new RuntimeException(); |
159 |
} |
160 |
} |
161 |
|
162 |
/**
|
163 |
* Dado el nombre de una tabla, se busca el fichero asociado a dicha tabla
|
164 |
* y se obtiene un datasource adecuado en funcion del tipo del fichero
|
165 |
* accediendo al subsistema de drivers. Se utiliza internamente como
|
166 |
* nombre de la tabla el alias que se pasa como par?metro
|
167 |
*
|
168 |
* @param tableName Nombre de la tabla que se asocia con un fichero
|
169 |
* @param tableAlias Alias que tiene el DataSource en una instrucci?n
|
170 |
*
|
171 |
* @return DataSource que accede a dicha tabla
|
172 |
*
|
173 |
* @throws NoSuchTableException
|
174 |
* @throws DriverLoadException
|
175 |
*/
|
176 |
public static DataSource createRandomDataSource(String tableName, |
177 |
String tableAlias) throws NoSuchTableException, DriverLoadException { |
178 |
DefaultDataSource adapter = (DefaultDataSource) createRandomDataSource(tableName); |
179 |
adapter.setName(tableAlias); |
180 |
|
181 |
return adapter;
|
182 |
} |
183 |
|
184 |
/**
|
185 |
* Devuelve true si todas las tablas provienen del mismo data base
|
186 |
* management system
|
187 |
*
|
188 |
* @param tables Array de tablas
|
189 |
*
|
190 |
* @return boolean
|
191 |
*/
|
192 |
private static boolean sameDBMS(DataSource[] tables) { |
193 |
String dbms = tables[0].getDBMS(); |
194 |
|
195 |
for (int i = 1; i < tables.length; i++) { |
196 |
if (!dbms.equals(tables[1].getDBMS())) { |
197 |
return false; |
198 |
} |
199 |
} |
200 |
|
201 |
return true; |
202 |
} |
203 |
|
204 |
/**
|
205 |
* Devuelve true si todas las tablas provienen directamente de un driver de
|
206 |
* base de datos, no son fruto de ninguna operaci?n
|
207 |
*
|
208 |
* @param tables Array de tablas
|
209 |
*
|
210 |
* @return boolean
|
211 |
*/
|
212 |
private static boolean allDrivers(DataSource[] tables) { |
213 |
for (int i = 0; i < tables.length; i++) { |
214 |
if (tables[i].getDriver() == null) { |
215 |
return false; |
216 |
} |
217 |
} |
218 |
|
219 |
return true; |
220 |
} |
221 |
|
222 |
/**
|
223 |
* Traduce los nombres en la instrucci?n, sustituyendo los nombres del
|
224 |
* GDBMS por los nombres de tabla en el sistema original
|
225 |
*
|
226 |
* @param adapter
|
227 |
*/
|
228 |
public static void translateNames(Adapter adapter) { |
229 |
//Se itera recursivamente sustituyendo el contenido de los tableRef
|
230 |
if (adapter instanceof TableRefAdapter) { |
231 |
SimpleNode n = adapter.getEntity(); |
232 |
n.first_token.image = (String) nameTable.get(n.first_token.image);
|
233 |
} else {
|
234 |
Adapter[] hijos = adapter.getChilds();
|
235 |
|
236 |
for (int i = 0; i < hijos.length; i++) { |
237 |
translateNames(hijos[i]); |
238 |
} |
239 |
} |
240 |
} |
241 |
|
242 |
/**
|
243 |
* A partir de una instrucci?n select se encarga de obtener el DataSource
|
244 |
* resultado de la ejecuci?n de dicha instrucci?n
|
245 |
*
|
246 |
* @param instr Instrucci?n select origen del datasource
|
247 |
*
|
248 |
* @return DataSource que accede a los datos resultado de ejecutar la
|
249 |
* select
|
250 |
*
|
251 |
* @throws DriverLoadException
|
252 |
* @throws DriverException Si fallo la lectura de la fuente de datos por
|
253 |
* parte del driver
|
254 |
* @throws SemanticException Si la instrucci?n tiene errores sem?nticos
|
255 |
* @throws IOException
|
256 |
*/
|
257 |
public static DataSource createRandomDataSource(SelectAdapter instr) |
258 |
throws DriverLoadException, DriverException, SemanticException,
|
259 |
IOException {
|
260 |
DataSource[] tables = instr.getTables(); |
261 |
|
262 |
//Estrategia de delegaci?n de la instrucci?n en el sgbd original de la tabla
|
263 |
if (sameDBMS(tables) && allDrivers(tables)) {
|
264 |
ReadDriver driver = tables[0].getDriver();
|
265 |
|
266 |
if (driver instanceof DBDriver) { |
267 |
DBDriver d = (DBDriver) driver; |
268 |
|
269 |
//Obtiene un driver del mismo tipo
|
270 |
Driver newDriver = dm.getDriver(((Driver) d).getName()); |
271 |
|
272 |
DBQueryDataSourceAdapter adapter = new DBQueryDataSourceAdapter();
|
273 |
adapter.setDriver((DBDriver) newDriver); |
274 |
DBDataSourceAdapter dbAdapter = ((DBDataSourceAdapter) tables[0]);
|
275 |
adapter.setConnectionString(dbAdapter.getHost(), dbAdapter.getPort(), dbAdapter.getDbName(), dbAdapter.getUser(), dbAdapter.getPassword()); |
276 |
translateNames(instr); |
277 |
adapter.setSQL(Utilities.getText(instr.getEntity()));
|
278 |
adapter.setName("");
|
279 |
adapter.setDBMS(null);
|
280 |
|
281 |
return adapter;
|
282 |
} |
283 |
} |
284 |
|
285 |
//Estrategia normal
|
286 |
Strategy strategy = StrategyManager.getStrategy(instr); |
287 |
|
288 |
return strategy.select(instr);
|
289 |
} |
290 |
|
291 |
/**
|
292 |
* Obtiene el DataSource resultado de ejecutar la instrucci?n de union
|
293 |
*
|
294 |
* @param instr instrucci?n de union
|
295 |
*
|
296 |
* @return DataSource
|
297 |
*
|
298 |
* @throws DriverException Si fallo la lectura de la fuente de datos por
|
299 |
* parte del driver
|
300 |
* @throws IOException Si se produce un error de entrada/salida
|
301 |
* @throws SemanticException Si la instrucci?n tiene errores sem?nticos
|
302 |
*/
|
303 |
public static DataSource createRandomDataSource(UnionAdapter instr) |
304 |
throws DriverException, IOException, SemanticException { |
305 |
Strategy strategy = StrategyManager.getStrategy(instr); |
306 |
|
307 |
return strategy.union(instr);
|
308 |
} |
309 |
|
310 |
/**
|
311 |
* Establece el DriverManager que se usar? para instanciar DataSource's.
|
312 |
* Este metodo debe ser invocado antes que ning?n otro
|
313 |
*
|
314 |
* @param dm El manager que se encarga de cargar los drivers
|
315 |
*/
|
316 |
public static void setDriverManager(DriverManager dm) { |
317 |
DataSourceFactory.dm = dm; |
318 |
} |
319 |
|
320 |
/**
|
321 |
* Informaci?n del driver
|
322 |
*
|
323 |
* @author Fernando Gonz?lez Cort?s
|
324 |
*/
|
325 |
public static class DriverInfo { |
326 |
public String name; |
327 |
public String dbms; |
328 |
public String driverName; |
329 |
} |
330 |
|
331 |
/**
|
332 |
* Informaci?n del driver de fichero
|
333 |
*
|
334 |
* @author Fernando Gonz?lez Cort?s
|
335 |
*/
|
336 |
public static class FileDriverInfo extends DriverInfo { |
337 |
public String file; |
338 |
} |
339 |
|
340 |
/**
|
341 |
* Informaci?n del driver de base de datos
|
342 |
*
|
343 |
* @author Fernando Gonz?lez Cort?s
|
344 |
*/
|
345 |
public static class DBDriverInfo extends DriverInfo { |
346 |
public String host; |
347 |
public int port; |
348 |
public String dbName; |
349 |
public String user; |
350 |
public String password; |
351 |
public String sqlQuery; |
352 |
public String driverInfo; |
353 |
} |
354 |
} |