KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ziclix > python > sql > PyExtendedCursor


1 /*
2  * Jython Database Specification API 2.0
3  *
4  * $Id: PyExtendedCursor.java,v 1.12 2005/02/23 04:26:18 bzimmer Exp $
5  *
6  * Copyright (c) 2001 brian zimmer <bzimmer@ziclix.com>
7  *
8  */

9 package com.ziclix.python.sql;
10
11 import org.python.core.Py;
12 import org.python.core.PyBuiltinFunctionSet;
13 import org.python.core.PyClass;
14 import org.python.core.PyList;
15 import org.python.core.PyObject;
16 import org.python.core.PyString;
17
18 import java.sql.DatabaseMetaData JavaDoc;
19 import java.sql.SQLException JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.Set JavaDoc;
22
23 /**
24  * A cursor with extensions to the DB API 2.0.
25  *
26  * @author brian zimmer
27  * @author last revised by $Author: bzimmer $
28  * @version $Revision: 1.12 $
29  */

30 public class PyExtendedCursor extends PyCursor {
31
32     /**
33      * Field __class__
34      */

35     public static PyClass __class__;
36
37     /**
38      * Method getPyClass
39      *
40      * @return PyClass
41      */

42     protected PyClass getPyClass() {
43         return __class__;
44     }
45
46     /**
47      * Field __members__
48      */

49     protected static PyList __members__;
50
51     /**
52      * Field __methods__
53      */

54     protected static PyList __methods__;
55
56     static {
57         PyObject[] m = new PyObject[9];
58
59         m[0] = new PyString("tables");
60         m[1] = new PyString("columns");
61         m[2] = new PyString("primarykeys");
62         m[3] = new PyString("foreignkeys");
63         m[4] = new PyString("procedures");
64         m[5] = new PyString("procedurecolumns");
65         m[6] = new PyString("statistics");
66         m[7] = new PyString("bestrow");
67         m[8] = new PyString("versioncolumns");
68         __methods__ = new PyList(m);
69
70         __methods__.extend(PyCursor.__methods__);
71
72         m = new PyObject[0];
73         __members__ = new PyList(m);
74
75         __members__.extend(PyCursor.__members__);
76     }
77
78     /**
79      * Constructor PyExtendedCursor
80      *
81      * @param connection
82      */

83     PyExtendedCursor(PyConnection connection) {
84         super(connection);
85     }
86
87     /**
88      * Constructor PyExtendedCursor
89      *
90      * @param connection
91      * @param dynamicFetch
92      */

93     PyExtendedCursor(PyConnection connection, boolean dynamicFetch) {
94         super(connection, dynamicFetch);
95     }
96
97     /**
98      * Constructor PyExtendedCursor
99      *
100      * @param connection
101      * @param dynamicFetch
102      * @param rsType
103      * @param rsConcur
104      */

105     PyExtendedCursor(PyConnection connection, boolean dynamicFetch, PyObject rsType, PyObject rsConcur) {
106         super(connection, dynamicFetch, rsType, rsConcur);
107     }
108
109     /**
110      * String representation of the object.
111      *
112      * @return a string representation of the object.
113      */

114     public String JavaDoc toString() {
115         return "<PyExtendedCursor object instance at " + Py.id(this) + ">";
116     }
117
118     /**
119      * Initializes the module.
120      *
121      * @param dict
122      */

123     static public void classDictInit(PyObject dict) {
124
125         PyCursor.classDictInit(dict);
126         dict.__setitem__("__version__", Py.newString("$Revision: 1.12 $").__getslice__(Py.newInteger(11), Py.newInteger(-2), null));
127         dict.__setitem__("tables", new ExtendedCursorFunc("tables", 100, 4, 4, "query for table information"));
128         dict.__setitem__("columns", new ExtendedCursorFunc("columns", 101, 4, 4, "query for column information"));
129         dict.__setitem__("primarykeys", new ExtendedCursorFunc("primarykeys", 102, 3, 3, "query for primary keys"));
130         dict.__setitem__("foreignkeys", new ExtendedCursorFunc("foreignkeys", 103, 6, 6, "query for foreign keys"));
131         dict.__setitem__("procedures", new ExtendedCursorFunc("procedures", 104, 3, 3, "query for procedures"));
132         dict.__setitem__("procedurecolumns", new ExtendedCursorFunc("procedurecolumns", 105, 4, 4, "query for procedures columns"));
133         dict.__setitem__("statistics", new ExtendedCursorFunc("statistics", 106, 5, 5, "description of a table's indices and statistics"));
134         dict.__setitem__("gettypeinfo", new ExtendedCursorFunc("gettypeinfo", 107, 0, 1, "query for sql type info"));
135         dict.__setitem__("gettabletypeinfo", new ExtendedCursorFunc("gettabletypeinfo", 108, 0, 1, "query for table types"));
136         dict.__setitem__("bestrow", new ExtendedCursorFunc("bestrow", 109, 3, 3, "optimal set of columns that uniquely identifies a row"));
137         dict.__setitem__("versioncolumns", new ExtendedCursorFunc("versioncolumns", 110, 3, 3, "columns that are automatically updated when any value in a row is updated"));
138
139         // hide from python
140
dict.__setitem__("classDictInit", null);
141         dict.__setitem__("toString", null);
142     }
143
144     /**
145      * Finds the attribute.
146      *
147      * @param name the name of the attribute of interest
148      * @return the value for the attribute of the specified name
149      */

150     public PyObject __findattr__(String JavaDoc name) {
151
152         if ("__methods__".equals(name)) {
153             return __methods__;
154         } else if ("__members__".equals(name)) {
155             return __members__;
156         }
157
158         return super.__findattr__(name);
159     }
160
161     /**
162      * Only table descriptions matching the catalog, schema, table name and type
163      * criteria are returned. They are ordered by TABLE_TYPE, TABLE_SCHEM and
164      * TABLE_NAME.
165      *
166      * @param qualifier
167      * @param owner
168      * @param table
169      * @param type
170      */

171     protected void tables(PyObject qualifier, PyObject owner, PyObject table, PyObject type) {
172
173         clear();
174
175         String JavaDoc q = getMetaDataName(qualifier);
176         String JavaDoc o = getMetaDataName(owner);
177         String JavaDoc t = getMetaDataName(table);
178         String JavaDoc[] y = null;
179
180         // postgresql interprets the types to be uppercase exclusively
181
// so we'll force this on everyone else as well
182
if (type != Py.None) {
183             String JavaDoc typeName = null;
184
185             if (isSeq(type)) {
186                 int len = type.__len__();
187
188                 y = new String JavaDoc[len];
189
190                 for (int i = 0; i < len; i++) {
191                     typeName = getMetaDataName(type.__getitem__(i));
192                     y[i] = (typeName == null) ? null : typeName.toUpperCase();
193                 }
194             } else {
195                 typeName = getMetaDataName(type.__getitem__(type));
196                 y = new String JavaDoc[]{(typeName == null) ? null : typeName.toUpperCase()};
197             }
198         }
199
200         try {
201             this.fetch.add(getMetaData().getTables(q, o, t, y));
202         } catch (SQLException JavaDoc e) {
203             throw zxJDBC.makeException(e);
204         }
205     }
206
207     /**
208      * Returns the columns for a table.
209      *
210      * @param qualifier
211      * @param owner
212      * @param table
213      * @param column
214      */

215     protected void columns(PyObject qualifier, PyObject owner, PyObject table, PyObject column) {
216
217         clear();
218
219         String JavaDoc q = getMetaDataName(qualifier);
220         String JavaDoc o = getMetaDataName(owner);
221         String JavaDoc t = getMetaDataName(table);
222         String JavaDoc c = getMetaDataName(column);
223
224         try {
225             this.fetch.add(getMetaData().getColumns(q, o, t, c));
226         } catch (SQLException JavaDoc e) {
227             throw zxJDBC.makeException(e);
228         }
229     }
230
231     /**
232      * Gets a description of the stored procedures available for the qualifier and owner.
233      *
234      * @param qualifier
235      * @param owner
236      * @param procedure
237      */

238     protected void procedures(PyObject qualifier, PyObject owner, PyObject procedure) {
239
240         clear();
241
242         String JavaDoc q = getMetaDataName(qualifier);
243         String JavaDoc o = getMetaDataName(owner);
244         String JavaDoc p = getMetaDataName(procedure);
245
246         try {
247             this.fetch.add(getMetaData().getProcedures(q, o, p));
248         } catch (SQLException JavaDoc e) {
249             throw zxJDBC.makeException(e);
250         }
251     }
252
253     /**
254      * Gets the columns for the procedure.
255      *
256      * @param qualifier
257      * @param owner
258      * @param procedure
259      * @param column
260      */

261     protected void procedurecolumns(PyObject qualifier, PyObject owner, PyObject procedure, PyObject column) {
262
263         clear();
264
265         String JavaDoc q = getMetaDataName(qualifier);
266         String JavaDoc o = getMetaDataName(owner);
267         String JavaDoc p = getMetaDataName(procedure);
268         String JavaDoc c = getMetaDataName(column);
269
270         try {
271             this.fetch.add(getMetaData().getProcedureColumns(q, o, p, c));
272         } catch (SQLException JavaDoc e) {
273             throw zxJDBC.makeException(e);
274         }
275     }
276
277     /**
278      * Gets a description of a table's primary key columns. They are ordered by
279      * COLUMN_NAME.
280      *
281      * @param qualifier a schema name
282      * @param owner an owner name
283      * @param table a table name
284      */

285     protected void primarykeys(PyObject qualifier, PyObject owner, PyObject table) {
286
287         clear();
288
289         String JavaDoc q = getMetaDataName(qualifier);
290         String JavaDoc o = getMetaDataName(owner);
291         String JavaDoc t = getMetaDataName(table);
292
293         try {
294             this.fetch.add(getMetaData().getPrimaryKeys(q, o, t));
295         } catch (SQLException JavaDoc e) {
296             throw zxJDBC.makeException(e);
297         }
298     }
299
300     /**
301      * Gets a description of the foreign key columns in the foreign key table
302      * that reference the primary key columns of the primary key table (describe
303      * how one table imports another's key.) This should normally return a single
304      * foreign key/primary key pair (most tables only import a foreign key from a
305      * table once.) They are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME,
306      * and KEY_SEQ.
307      *
308      * @param primaryQualifier
309      * @param primaryOwner
310      * @param primaryTable
311      * @param foreignQualifier
312      * @param foreignOwner
313      * @param foreignTable
314      */

315     protected void foreignkeys(PyObject primaryQualifier, PyObject primaryOwner, PyObject primaryTable, PyObject foreignQualifier, PyObject foreignOwner, PyObject foreignTable) {
316
317         clear();
318
319         String JavaDoc pq = getMetaDataName(primaryQualifier);
320         String JavaDoc po = getMetaDataName(primaryOwner);
321         String JavaDoc pt = getMetaDataName(primaryTable);
322         String JavaDoc fq = getMetaDataName(foreignQualifier);
323         String JavaDoc fo = getMetaDataName(foreignOwner);
324         String JavaDoc ft = getMetaDataName(foreignTable);
325
326         try {
327             this.fetch.add(getMetaData().getCrossReference(pq, po, pt, fq, fo, ft));
328         } catch (SQLException JavaDoc e) {
329             throw zxJDBC.makeException(e);
330         }
331     }
332
333     /**
334      * Gets a description of a table's indices and statistics. They are ordered by
335      * NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
336      *
337      * @param qualifier
338      * @param owner
339      * @param table
340      * @param unique
341      * @param accuracy
342      */

343     protected void statistics(PyObject qualifier, PyObject owner, PyObject table, PyObject unique, PyObject accuracy) {
344
345         clear();
346
347         Set skipCols = new HashSet JavaDoc();
348
349         skipCols.add(new Integer JavaDoc(12));
350
351         String JavaDoc q = getMetaDataName(qualifier);
352         String JavaDoc o = getMetaDataName(owner);
353         String JavaDoc t = getMetaDataName(table);
354         boolean u = unique.__nonzero__();
355         boolean a = accuracy.__nonzero__();
356
357         try {
358             this.fetch.add(getMetaData().getIndexInfo(q, o, t, u, a), skipCols);
359         } catch (SQLException JavaDoc e) {
360             throw zxJDBC.makeException(e);
361         }
362     }
363
364     /**
365      * Gets a description of the type information for a given type.
366      *
367      * @param type data type for which to provide information
368      */

369     protected void typeinfo(PyObject type) {
370
371         clear();
372
373         Set skipCols = new HashSet JavaDoc();
374
375         skipCols.add(new Integer JavaDoc(16));
376         skipCols.add(new Integer JavaDoc(17));
377
378         try {
379             this.fetch.add(getMetaData().getTypeInfo(), skipCols);
380         } catch (SQLException JavaDoc e) {
381             throw zxJDBC.makeException(e);
382         }
383
384         // if the type is non-null, then trim the result list down to that type only
385
// if(type != null &&!Py.None.equals(type)) {
386
// for(int i = 0; i < ((PyObject) this.results.get(0)).__len__(); i++) {
387
// PyObject row = ((PyObject) this.results.get(0)).__getitem__(new PyInteger(i));
388
// PyObject sqlType = row.__getitem__(new PyInteger(1));
389
// if(type.equals(sqlType)) {
390
// this.results.remove(0);
391
// this.results.add(0, new PyList(new PyObject[] {
392
// row
393
// }));
394
// }
395
// }
396
// }
397
}
398
399     /**
400      * Gets a description of possible table types.
401      */

402     protected void tabletypeinfo() {
403
404         clear();
405
406         try {
407             this.fetch.add(getMetaData().getTableTypes());
408         } catch (SQLException JavaDoc e) {
409             throw zxJDBC.makeException(e);
410         }
411     }
412
413     /**
414      * Gets a description of a table's optimal set of columns that uniquely
415      * identifies a row. They are ordered by SCOPE.
416      *
417      * @param qualifier
418      * @param owner
419      * @param table
420      */

421     protected void bestrow(PyObject qualifier, PyObject owner, PyObject table) {
422
423         clear();
424
425         String JavaDoc c = getMetaDataName(qualifier);
426         String JavaDoc s = getMetaDataName(owner);
427         String JavaDoc t = getMetaDataName(table);
428         int p = DatabaseMetaData.bestRowSession; // scope
429
boolean n = true; // nullable
430

431         try {
432             this.fetch.add(getMetaData().getBestRowIdentifier(c, s, t, p, n));
433         } catch (SQLException JavaDoc e) {
434             throw zxJDBC.makeException(e);
435         }
436     }
437
438     /**
439      * Gets a description of a table's columns that are automatically
440      * updated when any value in a row is updated. They are unordered.
441      *
442      * @param qualifier a schema name
443      * @param owner an owner name
444      * @param table a table name
445      */

446     protected void versioncolumns(PyObject qualifier, PyObject owner, PyObject table) {
447
448         clear();
449
450         String JavaDoc q = getMetaDataName(qualifier);
451         String JavaDoc o = getMetaDataName(owner);
452         String JavaDoc t = getMetaDataName(table);
453
454         try {
455             this.fetch.add(getMetaData().getVersionColumns(q, o, t));
456         } catch (SQLException JavaDoc e) {
457             throw zxJDBC.makeException(e);
458         }
459     }
460
461     /**
462      * Method getMetaDataName
463      *
464      * @param name
465      * @return String
466      */

467     protected String JavaDoc getMetaDataName(PyObject name) {
468
469         if (name == Py.None) {
470             return null;
471         }
472
473         String JavaDoc string = name.__str__().toString();
474
475         // see if the driver can help us
476
try {
477             if (getMetaData().storesLowerCaseIdentifiers()) {
478                 return string.toLowerCase();
479             } else if (getMetaData().storesUpperCaseIdentifiers()) {
480                 return string.toUpperCase();
481             }
482         } catch (SQLException JavaDoc e) {
483         }
484
485         // well we don't know yet so give it to the datahandler
486
return datahandler.getMetaDataName(name);
487     }
488 }
489
490 class ExtendedCursorFunc extends PyBuiltinFunctionSet {
491
492     ExtendedCursorFunc(String JavaDoc name, int index, int argcount, String JavaDoc doc) {
493         super(name, index, argcount, argcount, true, doc);
494     }
495
496     ExtendedCursorFunc(String JavaDoc name, int index, int minargs, int maxargs, String JavaDoc doc) {
497         super(name, index, minargs, maxargs, true, doc);
498     }
499
500     public PyObject __call__() {
501
502         PyExtendedCursor cursor = (PyExtendedCursor) __self__;
503
504         switch (index) {
505
506             case 107:
507                 cursor.typeinfo(Py.None);
508
509                 return Py.None;
510
511             case 108:
512                 cursor.tabletypeinfo();
513
514                 return Py.None;
515
516             default :
517                 throw argCountError(0);
518         }
519     }
520
521     public PyObject __call__(PyObject arga) {
522
523         PyExtendedCursor cursor = (PyExtendedCursor) __self__;
524
525         switch (index) {
526
527             case 107:
528                 cursor.typeinfo(arga);
529
530                 return Py.None;
531
532             default :
533                 throw argCountError(1);
534         }
535     }
536
537     public PyObject __call__(PyObject arga, PyObject argb, PyObject argc) {
538
539         PyExtendedCursor cursor = (PyExtendedCursor) __self__;
540
541         switch (index) {
542
543             case 102:
544                 cursor.primarykeys(arga, argb, argc);
545
546                 return Py.None;
547
548             case 104:
549                 cursor.procedures(arga, argb, argc);
550
551                 return Py.None;
552
553             case 109:
554                 cursor.bestrow(arga, argb, argc);
555
556                 return Py.None;
557
558             case 110:
559                 cursor.versioncolumns(arga, argb, argc);
560
561                 return Py.None;
562
563             default :
564                 throw argCountError(3);
565         }
566     }
567
568     public PyObject fancyCall(PyObject[] args) {
569
570         PyExtendedCursor cursor = (PyExtendedCursor) __self__;
571
572         switch (index) {
573
574             case 103:
575                 cursor.foreignkeys(args[0], args[1], args[2], args[3], args[4], args[5]);
576
577                 return Py.None;
578
579             case 106:
580                 cursor.statistics(args[0], args[1], args[2], args[3], args[4]);
581
582                 return Py.None;
583
584             default :
585                 throw argCountError(args.length);
586         }
587     }
588
589     public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3, PyObject arg4) {
590
591         PyExtendedCursor cursor = (PyExtendedCursor) __self__;
592
593         switch (index) {
594
595             case 100:
596                 cursor.tables(arg1, arg2, arg3, arg4);
597
598                 return Py.None;
599
600             case 101:
601                 cursor.columns(arg1, arg2, arg3, arg4);
602
603                 return Py.None;
604
605             case 105:
606                 cursor.procedurecolumns(arg1, arg2, arg3, arg4);
607
608                 return Py.None;
609
610             default :
611                 throw argCountError(4);
612         }
613     }
614 }
615
Popular Tags