Statistics
| Revision:

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
}