KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > lib > db > Postgres


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Rodrigo Westrupp
28  */

29
30 package com.caucho.quercus.lib.db;
31
32 import com.caucho.quercus.annotation.Optional;
33 import com.caucho.quercus.env.Env;
34 import com.caucho.quercus.env.LongValue;
35 import com.caucho.quercus.env.StringBuilderValue;
36 import com.caucho.quercus.env.StringValue;
37 import com.caucho.quercus.env.StringValueImpl;
38 import com.caucho.util.L10N;
39
40 import java.lang.reflect.Method JavaDoc;
41 import java.sql.Connection JavaDoc;
42 import java.sql.ResultSet JavaDoc;
43 import java.sql.SQLException JavaDoc;
44 import java.sql.Statement JavaDoc;
45 import java.util.HashMap JavaDoc;
46 import java.util.logging.Level JavaDoc;
47 import java.util.logging.Logger JavaDoc;
48
49 /**
50  * postgres connection class (postgres has NO object oriented API)
51  */

52 public class Postgres extends JdbcConnectionResource {
53   private static final Logger JavaDoc log = Logger.getLogger(Postgres.class.getName());
54   private static final L10N L = new L10N(Postgres.class);
55
56   PostgresResult _asyncResult;
57   PostgresStatement _asyncStmt;
58
59   // named prepared statements for postgres
60
private HashMap JavaDoc<String JavaDoc,PostgresStatement> _stmtTable
61     = new HashMap JavaDoc<String JavaDoc,PostgresStatement>();
62
63   // Postgres specific server error message
64
// org.postgresql.util.ServerErrorMessage
65
Object JavaDoc _serverErrorMessage;
66
67   public Postgres(Env env,
68                   @Optional("localhost") String JavaDoc host,
69                   @Optional String JavaDoc user,
70                   @Optional String JavaDoc password,
71                   @Optional String JavaDoc db,
72                   @Optional("5432") int port,
73                   @Optional String JavaDoc driver,
74                   @Optional String JavaDoc url)
75   {
76     super(env);
77
78     connectInternal(env, host, user, password, db, port, "", 0, driver, url);
79   }
80
81   /**
82    * Connects to the underlying database.
83    */

84   public boolean connectInternal(Env env,
85                                  @Optional("localhost") String JavaDoc host,
86                                  @Optional String JavaDoc userName,
87                                  @Optional String JavaDoc password,
88                                  @Optional String JavaDoc dbname,
89                                  @Optional("5432") int port,
90                                  @Optional String JavaDoc socket,
91                                  @Optional int flags,
92                                  @Optional String JavaDoc driver,
93                                  @Optional String JavaDoc url)
94   {
95     if (isConnected()) {
96       env.warning(L.l("Connection is already opened to '{0}'", this));
97       return false;
98     }
99
100     try {
101
102       if (host == null || host.equals(""))
103         host = "localhost";
104
105       if (driver == null || driver.equals("")) {
106         driver = "org.postgresql.Driver";
107       }
108
109       if (url == null || url.equals("")) {
110         url = "jdbc:postgresql://" + host + ":" + port + "/" + dbname;
111       }
112
113       Connection JavaDoc jConn = env.getConnection(driver, url, userName, password);
114
115       setConnection(host, userName, password, dbname, port, jConn, driver, url);
116
117       return true;
118
119     } catch (SQLException JavaDoc e) {
120       env.warning("A link to the server could not be established. " + e.toString());
121       env.setSpecialValue("postgres.connectErrno",new LongValue(e.getErrorCode()));
122       env.setSpecialValue("postgres.connectError", new StringValueImpl(e.getMessage()));
123
124       log.log(Level.FINE, e.toString(), e);
125
126       return false;
127     } catch (Exception JavaDoc e) {
128       env.warning("A link to the server could not be established. " + e.toString());
129       env.setSpecialValue("postgres.connectError", new StringValueImpl(e.getMessage()));
130
131       log.log(Level.FINE, e.toString(), e);
132       return false;
133     }
134   }
135
136   /**
137    * returns a prepared statement
138    */

139   public PostgresStatement prepare(Env env, String JavaDoc query)
140   {
141     PostgresStatement stmt = new PostgresStatement((Postgres)validateConnection());
142
143     stmt.prepare(query);
144
145     return stmt;
146   }
147
148   /**
149    * Executes a query.
150    *
151    * @param sql the escaped query string (can contain escape sequences like `\n' and `\Z')
152    *
153    * @return a {@link JdbcResultResource}, or null for failure
154    */

155   public PostgresResult query(String JavaDoc sql)
156   {
157     return (PostgresResult) realQuery(sql);
158   }
159
160   /**
161    * Creates a database-specific result.
162    */

163   protected JdbcResultResource createResult(Statement JavaDoc stmt,
164                                             ResultSet JavaDoc rs)
165   {
166     return new PostgresResult(stmt, rs, this);
167   }
168
169   public void setAsynchronousResult(PostgresResult asyncResult)
170   {
171     _asyncResult = asyncResult;
172   }
173
174   public PostgresResult getAsynchronousResult()
175   {
176     return _asyncResult;
177   }
178
179   public PostgresStatement getAsynchronousStatement()
180   {
181     return _asyncStmt;
182   }
183
184   public void setAsynchronousStatement(PostgresStatement asyncStmt)
185   {
186     _asyncStmt = asyncStmt;
187   }
188
189   public void putStatement(String JavaDoc name,
190                            PostgresStatement stmt)
191   {
192     _stmtTable.put(name, stmt);
193   }
194
195   public PostgresStatement getStatement(String JavaDoc name)
196   {
197     return _stmtTable.get(name);
198   }
199
200   public PostgresStatement removeStatement(String JavaDoc name)
201   {
202     return _stmtTable.remove(name);
203   }
204
205   /**
206    * This function is overriden in Postgres to keep
207    * result set references for php/430a (see also php/1f33)
208    */

209   protected void keepResourceValues(Statement JavaDoc stmt)
210   {
211     setResultResource(createResult(stmt, null));
212   }
213
214   /**
215    * This function is overriden in Postgres to keep
216    * statement references for php/430a
217    */

218   protected boolean keepStatementOpen()
219   {
220     return true;
221   }
222
223   /**
224    * Escape the given string for SQL statements.
225    *
226    * @param str a string
227    * @return the string escaped for SQL statements
228    */

229   protected StringBuilderValue realEscapeString(StringValue str)
230   {
231     StringBuilderValue buf = new StringBuilderValue(str.length());
232
233     final int strLength = str.length();
234
235     for (int i = 0; i < strLength; i++) {
236       char c = str.charAt(i);
237
238       switch (c) {
239       case '\u0000':
240         buf.append('\\');
241         buf.append('\u0000');
242         break;
243       case '\n':
244         buf.append('\\');
245         buf.append('n');
246         break;
247       case '\r':
248         buf.append('\\');
249         buf.append('r');
250         break;
251       case '\\':
252         buf.append('\\');
253         buf.append('\\');
254         break;
255       case '\'':
256         buf.append('\'');
257         buf.append('\'');
258         break;
259       case '"':
260         // pg_escape_string does nothing about it.
261
// buf.append('\\');
262
buf.append('\"');
263         break;
264       case '\032':
265         buf.append('\\');
266         buf.append('Z');
267         break;
268       default:
269         buf.append(c);
270         break;
271       }
272     }
273
274     return buf;
275   }
276
277   /**
278    * This function is overriden in Postgres to clear
279    * any postgres specific server error message
280    */

281   protected void clearErrors()
282   {
283     super.clearErrors();
284     _serverErrorMessage = null;
285   }
286
287   /**
288    * This function is overriden in Postgres to save
289    * the postgres specific server error message
290    */

291   protected void saveErrors(SQLException JavaDoc e)
292   {
293     try {
294       super.saveErrors(e);
295
296       // Get the postgres specific server error message
297
Class JavaDoc cl = Class.forName("org.postgresql.util.PSQLException");
298       Method JavaDoc method = cl.getDeclaredMethod("getServerErrorMessage", null);
299       _serverErrorMessage = method.invoke(e, new Object JavaDoc[] {});
300     } catch (Exception JavaDoc ex) {
301       log.log(Level.FINE, ex.toString(), ex);
302     }
303   }
304
305   /**
306    * Return the postgres server specific error message
307    */

308   protected Object JavaDoc getServerErrorMessage()
309   {
310     return _serverErrorMessage;
311   }
312
313   public String JavaDoc toString()
314   {
315     if (isConnected())
316       return "Postgres[" + getHost() + "]";
317     else
318       return "Postgres[]";
319   }
320 }
321
Popular Tags