1 package net.sourceforge.phpdt.sql.sql;
3 import java.io.ByteArrayOutputStream;
5 import java.io.InputStream;
6 import java.io.PrintWriter;
8 import java.io.StringWriter;
10 import java.net.URLClassLoader;
11 import java.sql.Connection;
12 import java.sql.DatabaseMetaData;
13 import java.sql.Driver;
14 import java.sql.ResultSet;
15 import java.sql.ResultSetMetaData;
16 import java.sql.SQLException;
17 import java.sql.Statement;
18 import java.util.ArrayList;
19 import java.util.Hashtable;
20 import java.util.Properties;
21 import java.util.Vector;
23 import net.sourceforge.phpdt.sql.IConstants;
24 import net.sourceforge.phpdt.sql.adapters.AdapterFactory;
25 import net.sourceforge.phpdt.sql.adapters.DatabaseAdapter;
26 import net.sourceforge.phpdt.sql.adapters.NoSuchAdapterException;
27 import net.sourceforge.phpdt.sql.bookmarks.Bookmark;
28 import net.sourceforge.phpdt.sql.view.LogConstants;
29 import net.sourceforge.phpdt.sql.view.LogProxy;
31 public class MultiSQLServer extends Thread implements IConstants, LogConstants {
32 private static final int STREAM = 1024 * 2;
33 public static final String USERNAME = "user";
34 public static final String PASSWORD = "password";
35 private static MultiSQLServer instance = null;
36 private Hashtable classLoaderCache = new Hashtable();
37 private Connection con = null;
38 boolean running = true;
39 private Bookmark current = null;
40 private MultiSQLServer() {
43 public synchronized static MultiSQLServer getInstance() {
44 if (instance == null) {
45 instance = new MultiSQLServer();
50 public Bookmark getConnected() {
54 public void commit() {
55 LogProxy log = LogProxy.getInstance();
58 } catch (SQLException e) {
59 log.addText(ERROR, "Error commiting: " + e);
60 StringWriter writer = new StringWriter();
61 e.printStackTrace(new PrintWriter(writer));
62 log.addText(ERROR, writer.toString());
66 public void rollback() {
67 LogProxy log = LogProxy.getInstance();
70 } catch (SQLException e) {
71 log.addText(ERROR, "Error rolling back: " + e);
72 StringWriter writer = new StringWriter();
73 e.printStackTrace(new PrintWriter(writer));
74 log.addText(ERROR, writer.toString());
78 public void setAutoCommit(boolean enabled) {
79 LogProxy log = LogProxy.getInstance();
82 con.setAutoCommit(enabled);
84 log.addText(ERROR, "Please connect before setting autocommit");
86 } catch (SQLException e) {
87 log.addText(ERROR, "Error setting autocommit: " + e);
88 StringWriter writer = new StringWriter();
89 e.printStackTrace(new PrintWriter(writer));
90 log.addText(ERROR, writer.toString());
94 public DatabaseAdapter getCurrentAdapter() {
95 LogProxy log = LogProxy.getInstance();
97 AdapterFactory factory = AdapterFactory.getInstance();
98 return factory.getAdapter(current.getType());
99 } catch (NoSuchAdapterException e) {
102 "Invalid database type: ->" + current.getType() + "<-");
106 public void disconnect(Bookmark b) {
108 LogProxy log = LogProxy.getInstance();
113 log.addText(RESULTS, "Disconnected from: " + b.getName());
114 } catch (Exception e) {
117 "Error Disonnecting to: " + b.getName() + ":" + e.toString());
118 StringWriter writer = new StringWriter();
119 e.printStackTrace(new PrintWriter(writer));
120 log.addText(ERROR, writer.toString());
124 public void shutdown() {
125 LogProxy log = LogProxy.getInstance();
131 } catch (SQLException e) {
132 StringWriter writer = new StringWriter();
133 e.printStackTrace(new PrintWriter(writer));
134 log.addText(ERROR, writer.toString());
138 public void dumpDatabaseData() {
139 LogProxy log = LogProxy.getInstance();
141 DatabaseMetaData metadata = con.getMetaData();
144 "[METADATA] Database type: " + metadata.getDatabaseProductName());
145 if (metadata.supportsCatalogsInDataManipulation()) {
148 "[METADATA] Database does support catalog in data manipulation");
152 "[METADATA] Database does not support catalog in data manipulation");
154 if (metadata.supportsSchemasInDataManipulation()) {
157 "[METADATA] Database does support schema in data manipulation");
161 "[METADATA] Database does not support schema in data manipulation");
163 if (metadata.supportsCatalogsInTableDefinitions()) {
166 "[METADATA] Database does support catalogs in table definitions");
170 "[METADATA] Database does not support catalogs in table definitions");
174 "[METADATA] Catalog Separator: " + metadata.getCatalogSeparator());
177 "[METADATA] Catalog Term: " + metadata.getCatalogTerm());
178 ResultSet set = metadata.getCatalogs();
179 ArrayList catalogList = new ArrayList();
180 catalogList.add(null);
182 catalogList.add(set.getString(1));
185 StringBuffer catalogOutput = new StringBuffer();
186 catalogOutput.append("[CATALOG LIST] [");
187 for (int i = 0; i < catalogList.size(); i++) {
188 String name = (String) catalogList.get(i);
189 catalogOutput.append(name + ", ");
191 catalogOutput.append("]");
192 log.addText(WARNING, catalogOutput.toString());
194 set = metadata.getSchemas();
195 ArrayList schemaList = new ArrayList();
198 schemaList.add(set.getString(1));
201 StringBuffer schemaOutput = new StringBuffer();
202 schemaOutput.append("[SCHEMA LIST] [");
203 for (int i = 0; i < schemaList.size(); i++) {
204 String name = (String) schemaList.get(i);
205 schemaOutput.append(name + ", ");
207 schemaOutput.append("]");
208 log.addText(WARNING, schemaOutput.toString());
210 ArrayList tableTypes = new ArrayList();
211 set = metadata.getTableTypes();
213 tableTypes.add(set.getString(1));
217 StringBuffer tableListOutput = new StringBuffer();
218 tableListOutput.append("[TABLE LIST] [");
219 for (int i = 0; i < tableTypes.size(); i++) {
220 String name = (String) tableTypes.get(i);
221 tableListOutput.append(name + ", ");
223 tableListOutput.append("]");
224 log.addText(WARNING, tableListOutput.toString());
226 } catch (Exception e) {
227 log.addText(ERROR, "Error occured: " + e);
228 StringWriter writer = new StringWriter();
229 e.printStackTrace(new PrintWriter(writer));
230 log.addText(ERROR, writer.toString());
234 * type = "TABLE" "VIEW" "SEQUENCE"
236 public Vector listTables(String schema, String type) {
237 LogProxy log = LogProxy.getInstance();
238 Vector retVal = new Vector();
239 log.addText(QUERY, "Retrieving list [" + type + "]");
241 DatabaseMetaData meta = con.getMetaData();
242 ResultSet set = meta.getTableTypes();
243 int columnCount = set.getMetaData().getColumnCount();
245 for (int i = 1; i <= columnCount; i++) {
246 System.out.print(set.getMetaData().getColumnName(i) + "\t");
248 System.out.println();
250 for (int i = 1; i <= columnCount; i++) {
251 System.out.print(set.getString(i) + "\t");
253 System.out.println();
256 Vector types = new Vector();
257 set = meta.getTableTypes();
259 types.add(set.getString(1));
262 if (types.contains(type)) {
263 set = meta.getTables(null, schema, "%", new String[] { type });
265 String name = set.getString("TABLE_NAME");
266 String tableType = set.getString("TABLE_TYPE");
267 //System.out.println(name + ":" + tableType);
268 retVal.addElement(name);
272 log.addText(RESULTS, "Success");
273 } catch (SQLException e) {
274 log.addText(ERROR, "Error occured: " + e);
275 StringWriter writer = new StringWriter();
276 e.printStackTrace(new PrintWriter(writer));
277 log.addText(ERROR, writer.toString());
281 public boolean connect(Bookmark b) {
282 LogProxy log = LogProxy.getInstance();
283 log.addText(QUERY, "Connecting to: " + b.getName());
284 URL urls[] = new URL[1];
286 String driverFile = b.getDriverFile();
287 URLClassLoader loader = (URLClassLoader) classLoaderCache.get(driverFile);
288 if (loader == null) {
289 urls[0] = new File(driverFile).toURL();
290 loader = new URLClassLoader(urls);
291 classLoaderCache.put(driverFile, loader);
293 System.out.println("Creating new classloader");
297 System.out.println("Using classloader in cache");
300 Class driverClass = loader.loadClass(b.getDriver());
301 Driver driver = (Driver) driverClass.newInstance();
302 Properties props = new Properties();
303 props.put(USERNAME, b.getUsername());
304 props.put(PASSWORD, b.getPassword());
305 con = driver.connect(b.getConnect(), props);
308 "Error: Driver returned a null connection: " + b.toString());
311 log.addText(RESULTS, "Connected to: " + b.getName());
313 System.out.println("Connected");
316 } catch (Exception e) {
319 "Error Connecting to: " + b.getName() + ":" + e.toString());
320 StringWriter writer = new StringWriter();
321 e.printStackTrace(new PrintWriter(writer));
322 log.addText(ERROR, writer.toString());
326 public SQLResults execute(String s) {
327 return execute(s, -1, -1);
329 public SQLResults execute(String s, int startRow, int endRow) {
330 return execute(s, -1, -1, Integer.MAX_VALUE);
332 public SQLResults execute(
337 return execute(s, startRow, endRow, maxLength, "");
339 public SQLResults execute(
345 SQLResults results = new SQLResults();
348 System.out.println("Executing");
350 LogProxy log = LogProxy.getInstance();
351 log.addText(QUERY, "Executing Request [" + s + "]");
352 boolean metadata = false;
353 if (s.startsWith("METADATA")) {
358 String table = s.substring(s.indexOf(':') + 1);
359 String schema = current.getSchema();
360 String query = "SELECT * FROM " + schema + "." + table;
361 if (schema.equals("")) {
362 query = "SELECT * FROM " + table;
365 log.addText(QUERY, "Metadata Request [" + s + "]");
370 Statement stmt = con.createStatement();
371 boolean flag = stmt.execute(s);
372 results.setResultSet(flag);
374 int updates = stmt.getUpdateCount();
375 results.setUpdateCount(updates);
376 log.addText(RESULTS, "Success: " + updates + " records updated");
380 ResultSet set = stmt.getResultSet();
381 ResultSetMetaData metaData = set.getMetaData();
382 int columnCount = metaData.getColumnCount();
383 Vector columnNames = new Vector();
384 columnNames.addElement("ColumnName");
385 columnNames.addElement("Type");
386 columnNames.addElement("Size");
387 columnNames.addElement("Nullable");
388 columnNames.addElement("AutoIncrement");
389 results.setColumnNames(columnNames);
390 for (int i = 1; i <= columnCount; i++) {
391 Vector row = new Vector();
392 row.addElement(metaData.getColumnName(i));
393 row.addElement(metaData.getColumnTypeName(i));
394 int textSize = metaData.getColumnDisplaySize(i);
395 int precision = metaData.getPrecision(i);
396 int scale = metaData.getScale(i);
397 if (scale == 0 && precision == 0) {
398 row.addElement(Integer.toString(precision));
400 row.addElement(textSize + ", " + precision + ", " + scale);
402 int nullable = metaData.isNullable(i);
403 if (nullable == metaData.columnNoNulls) {
404 row.addElement("Not Null");
405 } else if (nullable == metaData.columnNullable) {
406 row.addElement("Nullable");
407 } else if (nullable == metaData.columnNullableUnknown) {
408 row.addElement("Nullable");
410 row.addElement("<Error>");
412 row.addElement(new Boolean(metaData.isAutoIncrement(i)).toString());
415 results.setHasMore(false);
417 ResultSet set = stmt.getResultSet();
418 ResultSetMetaData metaData = set.getMetaData();
419 int columnCount = metaData.getColumnCount();
420 Vector columnNames = new Vector();
421 for (int i = 1; i <= columnCount; i++) {
422 columnNames.addElement(metaData.getColumnName(i));
424 results.setColumnNames(columnNames);
425 Vector columnTypes = new Vector();
426 for (int i = 1; i <= columnCount; i++) {
427 columnTypes.addElement(metaData.getColumnTypeName(i));
429 results.setColumnsTypes(columnTypes);
430 int columnSizes[] = new int[columnCount];
431 for (int i = 1; i <= columnCount; i++) {
432 columnSizes[i - 1] = metaData.getColumnDisplaySize(i);
435 boolean exitEarly = false;
437 boolean disable = startRow < 1 || endRow < 1;
438 boolean start = rowCount >= startRow;
439 boolean end = rowCount <= endRow;
440 if (disable || (start && end)) {
441 Vector row = new Vector();
442 for (int i = 1; i <= columnCount; i++) {
444 if (columnSizes[i - 1] < STREAM
445 && columnSizes[i - 1] < maxLength) {
446 if (encoding.equals("")) {
447 value = set.getString(i);
449 value = new String(set.getBytes(i), encoding);
453 if (encoding.equals("")) {
454 Reader reader = set.getCharacterStream(i);
455 StringBuffer buffer = new StringBuffer();
456 if (reader != null) {
457 int retVal = reader.read();
459 while (retVal >= 0) {
460 buffer.append((char) retVal);
461 retVal = reader.read();
463 if (count > maxLength) {
464 buffer.append("...>>>");
470 value = buffer.toString();
472 InputStream binaryStream = set.getBinaryStream(i);
473 ByteArrayOutputStream baos = new ByteArrayOutputStream();
474 if (binaryStream != null) {
475 int retVal = binaryStream.read();
477 while (retVal >= 0) {
479 retVal = binaryStream.read();
481 if (count > maxLength) {
485 binaryStream.close();
487 value = new String(baos.toByteArray(), encoding);
489 } catch (Throwable e) {
490 // hack for mysql which doesn't implement
492 value = set.getString(i);
496 row.addElement("<NULL>");
498 row.addElement(value);
504 if (!disable && (rowCount > endRow)) {
510 results.setHasMore(set.next());
512 results.setMaxSize(rowCount);
513 results.setHasMore(false);
516 log.addText(RESULTS, "Success: result set displayed");
520 System.out.println("Executed");
521 System.out.println();
523 } catch (Exception e) {
524 results.setIsError(true);
525 log.addText(ERROR, "Error occured: " + e);
526 StringWriter writer = new StringWriter();
527 e.printStackTrace(new PrintWriter(writer));
528 log.addText(ERROR, writer.toString());