001: /*
002: * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005:
006: package com.sun.portal.search.db;
007:
008: import com.sun.portal.search.rdm.*;
009: import com.sun.portal.search.soif.*;
010: import com.sun.portal.search.util.*;
011:
012: import javax.naming.*;
013:
014: import java.util.*;
015: import java.util.regex.*;
016: import java.io.*;
017: import java.text.MessageFormat;
018:
019: import java.sql.*;
020: import javax.sql.*;
021:
022: /**
023: *
024: * Search engine interface implementation using JDBC to search a relational db
025: *
026: */
027: public class JDBCDb implements RDMDb {
028:
029: java.sql.Connection conn = null;
030: java.sql.Statement stmt = null;
031: String database;
032: String queryPattern;
033:
034: /**
035: * Store - creates a transaction for atomic indexing, if none supplied.
036: * @param st Token for search
037: * @param insoif SOIF document
038: * @param view Set of Attributes
039: * @param flags Options
040: * @param t RDM transaction
041: * @throws RDMException
042: */
043: public void store(SToken st, SOIF insoif, Set view, int flags,
044: RDMTransaction t) throws RDMException {
045: throw new RDMException("JDBCDb.store(): not implemented");
046: }
047:
048: /**
049: * Purge the database
050: * @param st Token for search
051: * @param t RDM transaction handle
052: * @throws RDMException
053: */
054: public int purge(SToken st, RDMTransaction t) throws RDMException {
055: throw new RDMException("JDBCDb.purge(): not implemented");
056: }
057:
058: /**
059: * Open a database
060: * @param st Token for search
061: * @param rootdir Database home dir
062: * @param dbname Name of database from root database
063: * @param rw RDMDb.WRITER or RDMDb.WRCREAT or RDMDb.READER
064: * @param mode Unix mode
065: * @throws RDMException
066: */
067: public void open(SToken st, String rootdir, String dbname, int rw,
068: int mode) throws RDMException {
069:
070: database = dbname;
071:
072: SOIF dbsoif = DbManager.getRootDbEntry(st, dbname);
073:
074: String driver = dbsoif.getValue("driver");
075: String dburl = dbsoif.getValue("databaseurl");
076: String dbusr = dbsoif.getValue("username");
077: String dbpwd = dbsoif.getValue("password");
078: queryPattern = dbsoif.getValue("querypattern");
079:
080: try {
081: //Load JDBC Driver
082: Class.forName(driver).newInstance();
083: //Getting connection...
084: conn = DriverManager.getConnection(dburl, dbusr, dbpwd);
085: } catch (Exception e) {
086: throw new RDMException(
087: "JDBCDb.open(): Failed to open jdbc connection", e);
088: }
089: }
090:
091: /**
092: * Close database and index extents
093: * @param st Token for search
094: * @throws RDMException
095: */
096: public void close(SToken st) throws RDMException {
097: try {
098: conn.close();
099: } catch (Exception e) {
100: throw new RDMException(
101: "JDBCDb.close(): Error during close()", e);
102: }
103: }
104:
105: /**
106: * Obtain the name for the search engine interface
107: */
108: public String getName() {
109: return "JDBC Search";
110: }
111:
112: /**
113: * Submit the query to the search engine
114: * @param st Token for search
115: * @param queryString Search query
116: * @param numHits Number of hits
117: * @param view Set of attributes to be retrieved
118: * @param sortOrder Order for sorting the results
119: * @param t RDM transaction handle
120: * @return RDMResultSet
121: * @throws RDMException
122: */
123: public RDMResultSet search(SToken st, String queryString,
124: int numHits, Set view, String sortOrder, RDMTransaction t)
125: throws RDMException {
126:
127: ResultSet srs;
128: DatabaseMetaData dmd;
129: String query;
130:
131: if (isSQLQuery(queryString)) {
132: query = queryString;
133: } else {
134: Object[] arguments = { queryString };
135: query = getSQLQuery(arguments, queryPattern);
136: }
137:
138: try {
139: srs = jdbcSearch(query, numHits, view);
140: dmd = conn.getMetaData();
141: } catch (Exception e) {
142: throw new RDMException(e);
143: }
144:
145: JDBCResultSet js = new JDBCResultSet(st, this , query, t);
146: js.setJDBCSearchResult(srs, dmd);
147: return js;
148: }
149:
150: /**
151: * Search the relational db
152: * @param query Search filter
153: * @param numHits Number of search hits
154: * @param view Set of Attributes
155: * @return ResultSet
156: * @throws RDMException
157: */
158: ResultSet jdbcSearch(String query, int numHits, Set view)
159: throws Exception {
160: ResultSet rs;
161:
162: try {
163: // Getting statement...
164: stmt = conn.createStatement();
165: // Executing query...
166: rs = stmt.executeQuery(query);
167: } catch (Exception e) {
168: throw new RDMException(e);
169: }
170:
171: return rs;
172: }
173:
174: /**
175: * Transform the query format to SQL based on the argument pattern
176: * @param arguments Query arguments
177: * @param patterm Query pattern in SQL format
178: * @return a query string that is in the SQL format defined by "pattern"
179: */
180: private String getSQLQuery(Object[] arguments, String pattern) {
181:
182: boolean singlequote = false;
183: MessageFormat queryFormat;
184: String query;
185:
186: if (pattern.indexOf("'") != -1) {
187: singlequote = true;
188: }
189:
190: if (singlequote) {
191: queryFormat = new MessageFormat(pattern.replace('\'', '^'));
192: query = (queryFormat.format(arguments)).replace('^', '\'');
193: } else {
194: queryFormat = new MessageFormat(pattern);
195: query = queryFormat.format(arguments);
196: }
197:
198: return query;
199:
200: }
201:
202: /**
203: * Check if the query is a SQL statement
204: * @param query Search query
205: * @return true or false
206: */
207: private boolean isSQLQuery(String qString) {
208:
209: String qs = qString.toLowerCase();
210:
211: if (qs.indexOf("select") != -1
212: && qs.indexOf("select") < qs.indexOf("from"))
213: return true;
214: else
215: return false;
216: }
217:
218: /**
219: * Get search count
220: * @param st Token for search
221: * @param t RDM transaction handle
222: * @return Number of docs.
223: */
224: public int count(SToken st, RDMTransaction t) throws RDMException {
225: return 250000000;
226: }
227:
228: /**
229: * Delete RD from database
230: * @param st Token for search
231: * @param s SOIF document
232: * @param view Set of attributes
233: * @param flags Options
234: * @param t RDM transaction handle
235: * @throws RDMException
236: */
237: public void delete(SToken st, SOIF s, Set view, int flags,
238: RDMTransaction t) throws RDMException {
239: throw new RDMException("JDBCDb.delete() not implemented");
240: }
241:
242: /**
243: * Update an RD with attributes set in View
244: * @param st Token for search
245: * @param insoif SOIF document
246: * @param view Set of Attributes
247: * @param flags Options
248: * @param t RDM transaction
249: * @throws RDMException
250: */
251: public void update(SToken st, SOIF insoif, Set view, int flags,
252: RDMTransaction t) throws RDMException {
253: throw new RDMException("JDBCDb.update() not implemented");
254: }
255:
256: /**
257: * Retrieve RD from database, filtered by view
258: * @param st Token for search
259: * @param url URL string
260: * @param view Set of Attributes
261: * @param flags Options
262: * @param t RDM transaction
263: * @throws RDMException
264: */
265: public SOIF fetch(SToken st, String url, Set view, int flags,
266: RDMTransaction t) throws RDMException {
267: throw new RDMException("JDBCDb.fetch() not implemented");
268: }
269:
270: /**
271: * Optimize the db
272: * @param st Token for search
273: * @throws RDMException
274: */
275: public void optimize(SToken st) throws RDMException {
276: throw new RDMException("JDBCDb.optimize() not implemented");
277: }
278:
279: /**
280: * Batch Index
281: * @param st Token for search
282: * @throws RDMException
283: */
284: public void indexBatch(SToken st) throws RDMException {
285: throw new RDMException("JDBCDb.indexBatch() not implemented");
286: }
287:
288: /**
289: * Recover the db - must be run stand alone (ie, no one else has the db open)
290: * @param st Token for search
291: * @param dbhome Database home dir
292: * @param fatal Option
293: * @throws RDMException
294: */
295: public void recover(SToken st, String dbhome, boolean fatal)
296: throws RDMException {
297: throw new RDMException("JDBCDb.recover() not implemented");
298: }
299:
300: }
|