1 package example;
2
3 import java.io;
4 import java.sql;
5 import org.postgresql.largeobject;
6
7 /**
8 * This test attempts to create a blob in the database, then to read
9 * it back.
10 *
11 * Important note: You will notice we import the org.postgresql.largeobject
12 * package, but don't import the org.postgresql package. The reason for this is
13 * that importing postgresql can confuse javac (we have conflicting class names
14 * in org.postgresql.* and java.sql.*). This doesn't cause any problems, as
15 * long as no code imports org.postgresql.
16 *
17 * Under normal circumstances, code using any jdbc driver only needs to import
18 * java.sql, so this isn't a problem.
19 *
20 * It's only if you use the non jdbc facilities, do you have to take this into
21 * account.
22 *
23 */
24
25 public class blobtest
26 {
27 Connection db;
28 Statement s;
29 LargeObjectManager lobj;
30
31 public blobtest(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException
32 {
33 String url = args[0];
34 String usr = args[1];
35 String pwd = args[2];
36
37 // Load the driver
38 Class.forName("org.postgresql.Driver");
39
40 // Connect to database
41 System.out.println("Connecting to Database URL = " + url);
42 db = DriverManager.getConnection(url, usr, pwd);
43
44 // This is required for all LargeObject calls
45 System.out.println("Connected... First turn off autoCommit()");
46 db.setAutoCommit(false);
47
48 System.out.println("Now creating a statement");
49 s = db.createStatement();
50
51 // Now run tests using postgresql's own Large object api
52 // NOTE: The methods shown in this example are _NOT_ JDBC, but are
53 // an implementation of the calls found in libpq. Unless you need to
54 // use this functionality, look at the jdbc tests on how to access blobs.
55 ownapi();
56
57 // Now run tests using JDBC methods
58 //jdbcapi(db,s);
59
60 // Finally close the database
61 System.out.println("Now closing the connection");
62 s.close();
63 db.close();
64
65 }
66
67 /**
68 * Now this is an extension to JDBC, unique to postgresql. Here we fetch
69 * an PGlobj object, which provides us with access to postgresql's
70 * large object api.
71 */
72 public void ownapi() throws FileNotFoundException, IOException, SQLException
73 {
74 System.out.println("\n----------------------------------------------------------------------\nTesting postgresql large object api\n----------------------------------------------------------------------\n");
75
76 // Internally, the driver provides JDBC compliant methods to access large
77 // objects, however the unique methods available to postgresql makes
78 // things a little easier.
79 System.out.println("Gaining access to large object api");
80 lobj = ((org.postgresql.Connection)db).getLargeObjectAPI();
81
82 int oid = ownapi_test1();
83 ownapi_test2(oid);
84
85 // Now call the jdbc2api test
86 jdbc2api(oid);
87
88 // finally delete the large object
89 ownapi_test3(oid);
90 System.out.println("\n\nOID="+oid);
91 }
92
93 private int ownapi_test1() throws FileNotFoundException, IOException, SQLException
94 {
95 System.out.println("Test 1 Creating a large object\n");
96
97 // Ok, test 1 is to create a large object. To do this, we use the create
98 // method.
99 System.out.println("Creating a large object");
100 int oid = lobj.create(LargeObjectManager.READ|LargeObjectManager.WRITE);
101 DriverManager.println("got large object oid="+oid);
102
103 LargeObject obj = lobj.open(oid,LargeObjectManager.WRITE);
104 DriverManager.println("got large object obj="+obj);
105
106 // Now open a test file - this class will do
107 System.out.println("Opening test source object");
108 FileInputStream fis = new FileInputStream("example/blobtest.java");
109
110 // copy the data
111 System.out.println("Copying file to large object");
112 byte buf[] = new byte[2048];
113 int s,tl=0;
114 while((s=fis.read(buf,0,2048))>0) {
115 System.out.println("Block size="+s+" offset="+tl);
116 //System.out.write(buf);
117 obj.write(buf,0,s);
118 tl+=s;
119 }
120 DriverManager.println("Copied "+tl+" bytes");
121
122 // Close the object
123 System.out.println("Closing object");
124 obj.close();
125
126 return oid;
127 }
128
129 private void ownapi_test2(int oid) throws FileNotFoundException, IOException, SQLException
130 {
131 System.out.println("Test 2 Reading a large object and save as a file\n");
132
133 // Now open the large object
134 System.out.println("Opening large object "+oid);
135 LargeObject obj = lobj.open(oid,LargeObjectManager.READ);
136 DriverManager.println("got obj="+obj);
137
138 // Now open a test file - this class will do
139 System.out.println("Opening test destination object");
140 FileOutputStream fos = new FileOutputStream("blob_testoutput");
141
142 // copy the data
143 System.out.println("Copying large object to file");
144 byte buf[] = new byte[512];
145 int s=obj.size();
146 int tl=0;
147 while(s>0) {
148 int rs = buf.length;
149 if(s<rs) rs=s;
150 obj.read(buf,0,rs);
151 fos.write(buf,0,rs);
152 tl+=rs;
153 s-=rs;
154 }
155 DriverManager.println("Copied "+tl+"/"+obj.size()+" bytes");
156
157 // Close the object
158 System.out.println("Closing object");
159 obj.close();
160 }
161
162 private void ownapi_test3(int oid) throws SQLException
163 {
164 System.out.println("Test 3 Deleting a large object\n");
165
166 // Now open the large object
167 System.out.println("Deleting large object "+oid);
168 lobj.unlink(oid);
169 }
170
171 //=======================================================================
172 // This tests the Blob interface of the JDBC 2.0 specification
173 public void jdbc2api(int oid) throws SQLException, IOException
174 {
175 System.out.println("Testing JDBC2 Blob interface:");
176 jdbc2api_cleanup();
177
178 System.out.println("Creating Blob on large object "+oid);
179 s.executeUpdate("create table basic (a oid)");
180
181 System.out.println("Inserting row");
182 s.executeUpdate("insert into basic values ("+oid+")");
183
184 System.out.println("Selecting row");
185 ResultSet rs = s.executeQuery("select a from basic");
186 if(rs!=null) {
187 while(rs.next()) {
188 System.out.println("Fetching Blob");
189 Blob b = rs.getBlob("a");
190 System.out.println("Blob.length() = "+b.length());
191 System.out.println("Characters 400-500:");
192 System.out.write(b.getBytes(400l,100));
193 System.out.println();
194 }
195 rs.close();
196 }
197
198 System.out.println("Cleaning up");
199 jdbc2api_cleanup();
200 }
201
202 private void jdbc2api_cleanup() throws SQLException
203 {
204 db.setAutoCommit(true);
205 try {
206 s.executeUpdate("drop table basic");
207 } catch(Exception ex) {
208 // We ignore any errors here
209 }
210 db.setAutoCommit(false);
211 }
212
213 //=======================================================================
214
215 public static void instructions()
216 {
217 System.err.println("java example.blobtest jdbc-url user password [debug]");
218 System.err.println("\nExamples:\n");
219 System.err.println("java -Djdbc.driver=org.postgresql.Driver example.blobtest jdbc:postgresql:test postgres password\nThis will run the tests on the database test on the local host.\n");
220 System.err.println("java -Djdbc.driver=org.postgresql.Driver example.blobtest jdbc:postgresql:test postgres password debug\nThis is the same as above, but will output debug information.\n");
221
222 System.err.println("This example tests the binary large object api of the driver.\nThis allows images or java objects to be stored in the database, and retrieved\nusing both postgresql's own api, and the standard JDBC api.");
223 }
224
225 public static void main(String args[])
226 {
227 System.out.println("PostgreSQL blobtest v7.0 rev 1\n");
228
229 if(args.length<3) {
230 instructions();
231 System.exit(1);
232 }
233
234 // This line outputs debug information to stderr. To enable this, simply
235 // add an extra parameter to the command line
236 if(args.length>3)
237 DriverManager.setLogStream(System.err);
238
239 // Now run the tests
240 try {
241 blobtest test = new blobtest(args);
242 } catch(Exception ex) {
243 System.err.println("Exception caught.\n"+ex);
244 ex.printStackTrace();
245 }
246 }
247 }