001: /*-------------------------------------------------------------------------
002: *
003: * Copyright (c) 2003-2005, PostgreSQL Global Development Group
004: *
005: * IDENTIFICATION
006: * $PostgreSQL: pgjdbc/org/postgresql/largeobject/LargeObjectManager.java,v 1.23 2007/07/27 10:15:36 jurka Exp $
007: *
008: *-------------------------------------------------------------------------
009: */
010: package org.postgresql.largeobject;
011:
012: import java.sql.ResultSet;
013: import java.sql.SQLException;
014: import org.postgresql.core.BaseConnection;
015: import org.postgresql.fastpath.Fastpath;
016: import org.postgresql.fastpath.FastpathArg;
017: import org.postgresql.util.PSQLException;
018: import org.postgresql.util.GT;
019: import org.postgresql.util.PSQLState;
020:
021: /**
022: * This class implements the large object interface to org.postgresql.
023: *
024: * <p>It provides methods that allow client code to create, open and delete
025: * large objects from the database. When opening an object, an instance of
026: * org.postgresql.largeobject.LargeObject is returned, and its methods then allow
027: * access to the object.
028: *
029: * <p>This class can only be created by org.postgresql.Connection
030: *
031: * <p>To get access to this class, use the following segment of code:
032: * <br><pre>
033: * import org.postgresql.largeobject.*;
034: *
035: * Connection conn;
036: * LargeObjectManager lobj;
037: *
038: * ... code that opens a connection ...
039: *
040: * lobj = ((org.postgresql.PGConnection)myconn).getLargeObjectAPI();
041: * </pre>
042: *
043: * <p>Normally, client code would use the getAsciiStream, getBinaryStream,
044: * or getUnicodeStream methods in ResultSet, or setAsciiStream,
045: * setBinaryStream, or setUnicodeStream methods in PreparedStatement to
046: * access Large Objects.
047: *
048: * <p>However, sometimes lower level access to Large Objects are required,
049: * that are not supported by the JDBC specification.
050: *
051: * <p>Refer to org.postgresql.largeobject.LargeObject on how to manipulate the
052: * contents of a Large Object.
053: *
054: * @see java.sql.ResultSet#getAsciiStream
055: * @see java.sql.ResultSet#getBinaryStream
056: * @see java.sql.ResultSet#getUnicodeStream
057: * @see java.sql.PreparedStatement#setAsciiStream
058: * @see java.sql.PreparedStatement#setBinaryStream
059: * @see java.sql.PreparedStatement#setUnicodeStream
060: */
061: public class LargeObjectManager {
062: // the fastpath api for this connection
063: private Fastpath fp;
064: private BaseConnection conn;
065:
066: /**
067: * This mode indicates we want to write to an object
068: */
069: public static final int WRITE = 0x00020000;
070:
071: /**
072: * This mode indicates we want to read an object
073: */
074: public static final int READ = 0x00040000;
075:
076: /**
077: * This mode is the default. It indicates we want read and write access to
078: * a large object
079: */
080: public static final int READWRITE = READ | WRITE;
081:
082: /**
083: * This prevents us being created by mere mortals
084: */
085: private LargeObjectManager() {
086: }
087:
088: /**
089: * Constructs the LargeObject API.
090: *
091: * <p><b>Important Notice</b>
092: * <br>This method should only be called by org.postgresql.Connection
093: *
094: * <p>There should only be one LargeObjectManager per Connection. The
095: * org.postgresql.Connection class keeps track of the various extension API's
096: * and it's advised you use those to gain access, and not going direct.
097: */
098: public LargeObjectManager(BaseConnection conn) throws SQLException {
099: this .conn = conn;
100: // We need Fastpath to do anything
101: this .fp = conn.getFastpathAPI();
102:
103: // Now get the function oid's for the api
104: //
105: // This is an example of Fastpath.addFunctions();
106: //
107: String sql;
108: if (conn.getMetaData().supportsSchemasInTableDefinitions()) {
109: sql = "SELECT p.proname,p.oid "
110: + " FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n "
111: + " WHERE p.pronamespace=n.oid AND n.nspname='pg_catalog' AND (";
112: } else {
113: sql = "SELECT proname,oid FROM pg_proc WHERE ";
114: }
115: sql += " proname = 'lo_open'" + " or proname = 'lo_close'"
116: + " or proname = 'lo_creat'"
117: + " or proname = 'lo_unlink'"
118: + " or proname = 'lo_lseek'"
119: + " or proname = 'lo_tell'" + " or proname = 'loread'"
120: + " or proname = 'lowrite'"
121: + " or proname = 'lo_truncate'";
122:
123: if (conn.getMetaData().supportsSchemasInTableDefinitions()) {
124: sql += ")";
125: }
126:
127: ResultSet res = conn.createStatement().executeQuery(sql);
128:
129: if (res == null)
130: throw new PSQLException(GT
131: .tr("Failed to initialize LargeObject API"),
132: PSQLState.SYSTEM_ERROR);
133:
134: fp.addFunctions(res);
135: res.close();
136:
137: conn.getLogger().debug("Large Object initialised");
138: }
139:
140: /**
141: * This opens an existing large object, based on its OID. This method
142: * assumes that READ and WRITE access is required (the default).
143: *
144: * @param oid of large object
145: * @return LargeObject instance providing access to the object
146: * @exception SQLException on error
147: * @deprecated As of 8.3, replaced by {@link #open(long)}
148: */
149: public LargeObject open(int oid) throws SQLException {
150: return open((long) oid);
151: }
152:
153: /**
154: * This opens an existing large object, based on its OID. This method
155: * assumes that READ and WRITE access is required (the default).
156: *
157: * @param oid of large object
158: * @return LargeObject instance providing access to the object
159: * @exception SQLException on error
160: */
161: public LargeObject open(long oid) throws SQLException {
162: return open(oid, READWRITE);
163: }
164:
165: /**
166: * This opens an existing large object, based on its OID
167: *
168: * @param oid of large object
169: * @param mode mode of open
170: * @return LargeObject instance providing access to the object
171: * @exception SQLException on error
172: * @deprecated As of 8.3, replaced by {@link #open(long, int)}
173: */
174: public LargeObject open(int oid, int mode) throws SQLException {
175: return open((long) oid, mode);
176: }
177:
178: /**
179: * This opens an existing large object, based on its OID
180: *
181: * @param oid of large object
182: * @param mode mode of open
183: * @return LargeObject instance providing access to the object
184: * @exception SQLException on error
185: */
186: public LargeObject open(long oid, int mode) throws SQLException {
187: if (conn.getAutoCommit())
188: throw new PSQLException(
189: GT
190: .tr("Large Objects may not be used in auto-commit mode."),
191: PSQLState.NO_ACTIVE_SQL_TRANSACTION);
192: return new LargeObject(fp, oid, mode);
193: }
194:
195: /**
196: * This creates a large object, returning its OID.
197: *
198: * <p>It defaults to READWRITE for the new object's attributes.
199: *
200: * @return oid of new object
201: * @exception SQLException on error
202: * @deprecated As of 8.3, replaced by {@link #createLO()}
203: */
204: public int create() throws SQLException {
205: return create(READWRITE);
206: }
207:
208: /**
209: * This creates a large object, returning its OID.
210: *
211: * <p>It defaults to READWRITE for the new object's attributes.
212: *
213: * @return oid of new object
214: */
215: public long createLO() throws SQLException {
216: return createLO(READWRITE);
217: }
218:
219: /**
220: * This creates a large object, returning its OID
221: *
222: * @param mode a bitmask describing different attributes of the new object
223: * @return oid of new object
224: * @exception SQLException on error
225: */
226: public long createLO(int mode) throws SQLException {
227: if (conn.getAutoCommit())
228: throw new PSQLException(
229: GT
230: .tr("Large Objects may not be used in auto-commit mode."),
231: PSQLState.NO_ACTIVE_SQL_TRANSACTION);
232: FastpathArg args[] = new FastpathArg[1];
233: args[0] = new FastpathArg(mode);
234: return fp.getOID("lo_creat", args);
235: }
236:
237: /**
238: * This creates a large object, returning its OID
239: *
240: * @param mode a bitmask describing different attributes of the new object
241: * @return oid of new object
242: * @exception SQLException on error
243: * @deprecated As of 8.3, replaced by {@link #createLO(int)}
244: */
245: public int create(int mode) throws SQLException {
246: long oid = createLO(mode);
247: return (int) oid;
248: }
249:
250: /**
251: * This deletes a large object.
252: *
253: * @param oid describing object to delete
254: * @exception SQLException on error
255: */
256: public void delete(long oid) throws SQLException {
257: FastpathArg args[] = new FastpathArg[1];
258: args[0] = Fastpath.createOIDArg(oid);
259: fp.fastpath("lo_unlink", false, args);
260: }
261:
262: /**
263: * This deletes a large object.
264: *
265: * <p>It is identical to the delete method, and is supplied as the C API uses
266: * unlink.
267: *
268: * @param oid describing object to delete
269: * @exception SQLException on error
270: * @deprecated As of 8.3, replaced by {@link #unlink(long)}
271: */
272: public void unlink(int oid) throws SQLException {
273: delete((long) oid);
274: }
275:
276: /**
277: * This deletes a large object.
278: *
279: * <p>It is identical to the delete method, and is supplied as the C API uses
280: * unlink.
281: *
282: * @param oid describing object to delete
283: * @exception SQLException on error
284: */
285: public void unlink(long oid) throws SQLException {
286: delete(oid);
287: }
288:
289: /**
290: * This deletes a large object.
291: *
292: * @param oid describing object to delete
293: * @exception SQLException on error
294: * @deprecated As of 8.3, replaced by {@link #delete(long)}
295: */
296: public void delete(int oid) throws SQLException {
297: delete((long) oid);
298: }
299:
300: }
|