KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > db > impl > Driver_Oracle


1 /*
2  * (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
3  * All rights reserved.
4  *
5  *
6  */

7
8 package com.hp.hpl.jena.db.impl;
9
10 import java.io.InputStream JavaDoc;
11 import java.io.OutputStream JavaDoc;
12 import java.io.StringBufferInputStream JavaDoc;
13 import java.io.UnsupportedEncodingException JavaDoc;
14 import java.sql.PreparedStatement JavaDoc;
15 import java.sql.ResultSet JavaDoc;
16 import java.sql.SQLException JavaDoc;
17 import java.sql.Statement JavaDoc;
18 import java.util.Iterator JavaDoc;
19
20 import com.hp.hpl.jena.db.IDBConnection;
21 import com.hp.hpl.jena.db.RDFRDBException;
22
23 /* <---- TO WORK WITH ORACLE, PREFIX THIS LINE WITH "//" (I.E., TO EXPOSE IMPORT STATEMENTS) -------
24 import oracle.jdbc.OracleResultSet;
25 import oracle.sql.BLOB;
26 import oracle.jdbc.OracleDatabaseMetaData;
27
28 /*--------------------------------------------------------------------*/

29
30 /**
31  * @author hkuno based on code by Dave Reynolds
32  *
33  * Extends DriverRDB with Oracle-specific parameters.
34  * Note: To use this class with Oracle:
35  * 1. Uncomment the import statements above.
36  * 2. Comment out the interface stubs below.
37  * 3. Uncomment the try block in setConnection below.
38  *
39  */

40    public class Driver_Oracle extends DriverRDB {
41
42 //* <----- TO WORK WITH ORACLE, PREFIX THIS LINE WITH "/*" (I.E., TO HIDE INTERFACE STUBS) ------
43

44     public interface BLOB extends java.sql.Blob JavaDoc {
45         OutputStream JavaDoc getBinaryOutputStream();
46         int getBufferSize();
47         boolean isOpen();
48         void close();
49     }
50     
51     private interface OracleResultSet extends ResultSet JavaDoc {
52             BLOB getBLOB(int i);
53     }
54     /*--------------------------------------------------------------------*/
55     
56     /** The name of the database type this driver supports */
57     
58     /**
59      * Constructor
60      */

61     public Driver_Oracle( ){
62         super();
63
64         String JavaDoc myPackageName = this.getClass().getPackage().getName();
65         
66         DATABASE_TYPE = "Oracle";
67         DRIVER_NAME = "oracle.jdbc.driver.OracleDriver";
68         
69         ID_SQL_TYPE = "INTEGER";
70         URI_COMPRESS = false;
71         INDEX_KEY_LENGTH_MAX = INDEX_KEY_LENGTH = 4000;
72         LONG_OBJECT_LENGTH_MAX = LONG_OBJECT_LENGTH = 250;
73         TABLE_NAME_LENGTH_MAX = 30;
74         /* 30 is a guesstimate. setConnection should be called
75          * immediately to get the correct value. */

76         IS_XACT_DB = true;
77         PRE_ALLOCATE_ID = true;
78         SKIP_DUPLICATE_CHECK = false;
79         SQL_FILE = "etc/oracle.sql";
80         
81         m_psetClassName = myPackageName + ".PSet_TripleStore_RDB";
82         m_psetReifierClassName = myPackageName + ".PSet_ReifStore_RDB";
83         
84         m_lsetClassName = myPackageName + ".SpecializedGraph_TripleStore_RDB";
85         m_lsetReifierClassName = myPackageName + ".SpecializedGraphReifier_RDB";
86         
87         
88         QUOTE_CHAR = '\'';
89         
90         DB_NAMES_TO_UPPER = true;
91         setTableNames(TABLE_NAME_PREFIX);
92     }
93     
94     /**
95      * Set the database connection
96      */

97     public void setConnection( IDBConnection dbcon ) {
98         m_dbcon = dbcon;
99 /* <---- TO WORK WITH ORACLE, PREFIX THIS LINE WITH "//" (I.E., TO EXPOSE TRY BLOCK) -------
100         try {
101             OracleDatabaseMetaData dmd = (OracleDatabaseMetaData)dbcon.getConnection().getMetaData();
102             if (dmd == null)
103                 throw new RDFRDBException("Oracle database metadata not available.");
104             TABLE_NAME_LENGTH_MAX = dmd.getMaxTableNameLength();
105             setTableNames(TABLE_NAME_PREFIX); // need to recheck that table names are not too long
106         } catch ( SQLException e ) {
107             throw new RDFRDBException("Problem accessing Oracle database metadata.");
108         }
109 /*--------------------------------------------------------------------*/

110         try {
111             // Properties defaultSQL = SQLCache.loadSQLFile(DEFAULT_SQL_FILE, null, ID_SQL_TYPE);
112
// m_sql = new SQLCache(SQL_FILE, defaultSQL, dbcon, ID_SQL_TYPE);
113
m_sql = new SQLCache(SQL_FILE, null, dbcon, ID_SQL_TYPE);
114         } catch (Exception JavaDoc e) {
115             e.printStackTrace( System.err );
116             logger.error("Unable to set connection for Driver:", e);
117         }
118     }
119     
120     /**
121      * Allocate an identifier for a new graph.
122      *
123      */

124     public int graphIdAlloc ( String JavaDoc graphName ) {
125         DBIDInt result = null;
126         int dbid = 0;
127         try {
128             String JavaDoc op = "insertGraph";
129             dbid = getInsertID(GRAPH_TABLE);
130             PreparedStatement JavaDoc ps = m_sql.getPreparedSQLStatement(op,GRAPH_TABLE);
131             ps.setInt(1,dbid);
132             ps.setString(2,graphName);
133             ps.executeUpdate();
134             m_sql.returnPreparedSQLStatement(ps);
135         } catch (SQLException JavaDoc e) {
136             throw new RDFRDBException("Failed to get last inserted ID: " + e);
137         }
138         return dbid;
139     }
140     
141     /**
142      * Dellocate an identifier for a graph.
143      *
144      */

145     public void graphIdDealloc ( int graphId ) {
146         DBIDInt result = null;
147         try {
148             String JavaDoc op = "deleteGraph";
149             PreparedStatement JavaDoc ps = m_sql.getPreparedSQLStatement(op,GRAPH_TABLE);
150             ps.setInt(1,graphId);
151             ps.executeUpdate();
152             m_sql.returnPreparedSQLStatement(ps);
153         } catch (SQLException JavaDoc e) {
154             throw new RDFRDBException("Failed to delete graph ID: " + e);
155         }
156         return;
157     }
158
159     public int getInsertID ( String JavaDoc tableName ) {
160         DBIDInt result = null;
161         try {
162             String JavaDoc op = "getInsertID";
163             PreparedStatement JavaDoc ps = m_sql.getPreparedSQLStatement(op,tableName);
164             ResultSet JavaDoc rs = ps.executeQuery();
165             if (rs.next()) {
166                 result = wrapDBID(rs.getObject(1));
167             } else
168                 throw new RDFRDBException("No insert ID");
169             m_sql.returnPreparedSQLStatement(ps);
170         } catch (SQLException JavaDoc e) {
171             throw new RDFRDBException("Failed to insert ID: " + e);
172         }
173         return result.getIntID();
174     }
175
176     
177     /**
178      * Return the parameters for table creation.
179      * 1) column type for subj, prop, obj.
180      * 2) column type for head.
181      * 3) table and index name prefix.
182      * @param param array to hold table creation parameters.
183      */

184     protected void getTblParams ( String JavaDoc [] param ) {
185         String JavaDoc objColType;
186         
187         // length of varchar columns in statement tables
188
if ( LONG_OBJECT_LENGTH > 4000 )
189             throw new RDFRDBException("Long object length specified (" + LONG_OBJECT_LENGTH +
190                     ") exceeds maximum sane length of 4000.");
191         if ( INDEX_KEY_LENGTH > 4000 )
192             throw new RDFRDBException("Index key length specified (" + INDEX_KEY_LENGTH +
193                     ") exceeds maximum sane length of 4000.");
194
195         objColType = "VARCHAR2(" + LONG_OBJECT_LENGTH + ")";
196         STRINGS_TRIMMED = false;
197         param[0] = objColType;
198         
199         // length of head column in literal tables
200
String JavaDoc headColType = "VARCHAR2(" + INDEX_KEY_LENGTH + ")";
201         param[1] = headColType;
202         param[2] = TABLE_NAME_PREFIX;
203     }
204     
205     /**
206     *
207     * Return the parameters for table creation.
208     * Generate the table name by counting the number of existing
209     * tables for the graph. This is not reliable if another client
210     * is concurrently trying to create a table so, if failure, we
211     * make several attempts to create the table.
212     */

213
214     protected String JavaDoc[] getCreateTableParams( int graphId, boolean isReif ) {
215         String JavaDoc [] parms = new String JavaDoc[3];
216         String JavaDoc [] res = new String JavaDoc[2];
217                 
218         getTblParams (parms);
219         int tblCnt = getTableCount(graphId);
220         res[0] = genTableName(graphId,tblCnt,isReif);
221         res[1] = parms[0];
222         return res;
223     }
224     
225     /**
226      * Return the parameters for database initialization.
227      */

228     protected String JavaDoc[] getDbInitTablesParams() {
229         String JavaDoc [] res = new String JavaDoc[3];
230         
231         getTblParams (res);
232         EOS_LEN = EOS.length();
233
234         return res;
235     }
236     
237     /**
238      * Insert a long object into the database.
239      * This assumes the object is not already in the database.
240      * @return the db index of the added literal
241      */

242     public DBIDInt addRDBLongObject(RDBLongObject lobj, String JavaDoc table) throws RDFRDBException {
243         DBIDInt longObjID = null;
244         try {
245             int argi = 1;
246             boolean save = m_dbcon.getConnection().getAutoCommit();
247             
248             String JavaDoc opname = (lobj.tail.length() > 0) ? "insertLongObjectEmptyTail" : "insertLongObject";
249             PreparedStatement JavaDoc ps = m_sql.getPreparedSQLStatement(opname, table);
250             int dbid = 0; // init only needed to satisy java compiler
251
if ( PRE_ALLOCATE_ID ) {
252                 dbid = getInsertID(table);
253                 ps.setInt(argi++,dbid);
254                 longObjID = wrapDBID(new Integer JavaDoc(dbid));
255             }
256              ps.setString(argi++, lobj.head);
257              if ( lobj.tail.length() > 0 ) {
258                 ps.setLong(argi++, lobj.hash);
259              } else {
260                 ps.setNull(argi++,java.sql.Types.BIGINT);
261              }
262             ps.executeUpdate();
263             m_sql.returnPreparedSQLStatement(ps);
264             
265             if ( lobj.tail.length() > 0) {
266                 if (! xactOp(xactIsActive)) {
267                   m_dbcon.getConnection().setAutoCommit(false);
268                 }
269                 opname = "getEmptyBLOB";
270                 String JavaDoc cmd = m_sql.getSQLStatement(opname, table, longObjID.getID().toString());
271                 Statement JavaDoc lobStmt = m_sql.getConnection().createStatement();
272                 ResultSet JavaDoc lrs = lobStmt.executeQuery(cmd);
273                 lrs.next();
274         
275                 BLOB blob = ((OracleResultSet) lrs).getBLOB(1);
276                 OutputStream JavaDoc outstream = blob.getBinaryOutputStream();
277                 int size = blob.getBufferSize();
278     
279                 int length = -1;
280                 InputStream JavaDoc instream = new StringBufferInputStream JavaDoc(lobj.tail);
281         
282                 // Buffer to hold chunks of data to being written to the Blob.
283
byte[] buffer = new byte[size];
284         
285                 while ((length = instream.read(buffer)) != -1)
286                     outstream.write(buffer,0,length);
287         
288                 if (blob.isOpen())
289                 blob.close();
290                 instream.close();
291                 outstream.close();
292                 lobStmt.close();
293                 if (! xactOp(xactIsActive)) {
294                     m_dbcon.getConnection().setAutoCommit(save);
295                 }
296             }
297
298             if ( !PRE_ALLOCATE_ID ) {
299                 dbid = getInsertID(table);
300                 longObjID = wrapDBID(new Integer JavaDoc(dbid));
301             }
302         } catch (Exception JavaDoc e1) {
303             /* DEBUG */ System.out.println("Problem on long object (l=" + lobj.head + ") " + e1 );
304             // System.out.println("ID is: " + id);
305
throw new RDFRDBException("Failed to add long object ", e1);
306         }
307         return longObjID;
308     }
309     
310
311
312 /**
313  * Retrieve LongObject from database.
314  */

315 protected RDBLongObject IDtoLongObject ( int dbid, String JavaDoc table ) {
316     RDBLongObject res = null;
317     try {
318                 String JavaDoc opName = "getLongObject";
319                 PreparedStatement JavaDoc ps = m_sql.getPreparedSQLStatement(opName, table);
320                 ps.setInt(1,dbid);
321                 OracleResultSet rs = (OracleResultSet) ps.executeQuery();
322                 if (rs.next()) {
323                    res = new RDBLongObject();
324                    res.head = rs.getString(1);
325                    BLOB blob = rs.getBLOB(2);
326                     
327                    if (blob != null) {
328                     int len = (int)blob.length();
329                     byte[] data = blob.getBytes(1,len);
330                     res.tail = new String JavaDoc(data, "UTF-8");
331                    } else {
332                     res.tail = "";
333                    }
334                 }
335                 rs.close();
336                 m_sql.returnPreparedSQLStatement(ps);
337             
338     } catch (SQLException JavaDoc e1) {
339         // /* DEBUG */ System.out.println("Literal truncation (" + l.toString().length() + ") " + l.toString().substring(0, 150));
340
throw new RDFRDBException("Failed to retrieve long object (SQL Exception): ", e1);
341     } catch (UnsupportedEncodingException JavaDoc e2) {
342         throw new RDFRDBException("Failed to retrieve long object (UnsupportedEncoding): ", e2);
343     }
344     return res;
345 }
346     
347 /**
348  * Drop all Jena-related sequences from database, if necessary.
349  * Override in subclass if sequences must be explicitly deleted.
350  */

351 public void clearSequences() {
352     Iterator JavaDoc seqIt = getSequences().iterator();
353     while (seqIt.hasNext()) {
354         removeSequence((String JavaDoc)seqIt.next());
355     }
356 }
357     
358 public String JavaDoc genSQLStringMatchLHS_IC(String JavaDoc var) {
359     return "UPPER(" + var + ")";
360 }
361
362 public String JavaDoc genSQLStringMatchRHS_IC(String JavaDoc strToMatch) {
363     return "UPPER(" + strToMatch + ")";
364 }
365
366 public String JavaDoc stringMatchEscapeChar() { return "\\"; }
367
368 public String JavaDoc genSQLStringMatchEscape() {
369     return " " + genSQLEscapeKW() + " '" + stringMatchEscapeChar() + "'";
370 }
371     
372
373
374
375
376     
377     
378     
379
380         
381 }
382
383 /*
384  * (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
385  * All rights reserved.
386  *
387  * Redistribution and use in source and binary forms, with or without
388  * modification, are permitted provided that the following conditions
389  * are met:
390  * 1. Redistributions of source code must retain the above copyright
391  * notice, this list of conditions and the following disclaimer.
392  * 2. Redistributions in binary form must reproduce the above copyright
393  * notice, this list of conditions and the following disclaimer in the
394  * documentation and/or other materials provided with the distribution.
395  * 3. The name of the author may not be used to endorse or promote products
396  * derived from this software without specific prior written permission.
397
398  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
399  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
400  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
401  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
402  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
403  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
404  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
405  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
406  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
407  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
408  */

409
Popular Tags