summaryrefslogtreecommitdiff
path: root/src/interfaces/jdbc/example/blobtest.java
blob: 271026250dd63ee646675e9d9f84b13e8ea65326 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
package example;

import java.io.*;
import java.sql.*;
import org.postgresql.largeobject.*;

/*
 * This test attempts to create a blob in the database, then to read
 * it back.
 *
 * Important note: You will notice we import the org.postgresql.largeobject
 * package, but don't import the org.postgresql package. The reason for this is
 * that importing postgresql can confuse javac (we have conflicting class names
 * in org.postgresql.* and java.sql.*). This doesn't cause any problems, as
 * long as no code imports org.postgresql.
 *
 * Under normal circumstances, code using any jdbc driver only needs to import
 * java.sql, so this isn't a problem.
 *
 * It's only if you use the non jdbc facilities, do you have to take this into
 * account.
 *
 */

public class blobtest
{
	Connection db;
	Statement s;
	LargeObjectManager lobj;

	public blobtest(String args[]) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException
	{
		String url = args[0];
		String usr = args[1];
		String pwd = args[2];

		// Load the driver
		Class.forName("org.postgresql.Driver");

		// Connect to database
		System.out.println("Connecting to Database URL = " + url);
		db = DriverManager.getConnection(url, usr, pwd);

		// This is required for all LargeObject calls
		System.out.println("Connected... First turn off autoCommit()");
		db.setAutoCommit(false);

		System.out.println("Now creating a statement");
		s = db.createStatement();

		// Now run tests using postgresql's own Large object api
		// NOTE: The methods shown in this example are _NOT_ JDBC, but are
		// an implementation of the calls found in libpq. Unless you need to
		// use this functionality, look at the jdbc tests on how to access blobs.
		ownapi();

		// Now run tests using JDBC methods
		//jdbcapi(db,s);

		// Finally close the database
		System.out.println("Now closing the connection");
		s.close();
		db.close();
	}

	/*
	 * Now this is an extension to JDBC, unique to postgresql. Here we fetch
	 * an PGlobj object, which provides us with access to postgresql's
	 * large object api.
	 */
	public void ownapi() throws FileNotFoundException, IOException, SQLException
	{
		System.out.println("\n----------------------------------------------------------------------\nTesting postgresql large object api\n----------------------------------------------------------------------\n");

		// Internally, the driver provides JDBC compliant methods to access large
		// objects, however the unique methods available to postgresql makes
		// things a little easier.
		System.out.println("Gaining access to large object api");
		lobj = ((org.postgresql.Connection)db).getLargeObjectAPI();

		int oid = ownapi_test1();
		ownapi_test2(oid);

		// Now call the jdbc2api test
		jdbc2api(oid);

		// finally delete the large object
		ownapi_test3(oid);
		System.out.println("\n\nOID=" + oid);
	}

	private int ownapi_test1() throws FileNotFoundException, IOException, SQLException
	{
		System.out.println("Test 1 Creating a large object\n");

		// Ok, test 1 is to create a large object. To do this, we use the create
		// method.
		System.out.println("Creating a large object");
		int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
		DriverManager.println("got large object oid=" + oid);

		LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
		DriverManager.println("got large object obj=" + obj);

		// Now open a test file - this class will do
		System.out.println("Opening test source object");
		FileInputStream fis = new FileInputStream("example/blobtest.java");

		// copy the data
		System.out.println("Copying file to large object");
		byte buf[] = new byte[2048];
		int s, tl = 0;
		while ((s = fis.read(buf, 0, 2048)) > 0)
		{
			System.out.println("Block size=" + s + " offset=" + tl);
			//System.out.write(buf);
			obj.write(buf, 0, s);
			tl += s;
		}
		DriverManager.println("Copied " + tl + " bytes");

		// Close the object
		System.out.println("Closing object");
		obj.close();

		return oid;
	}

	private void ownapi_test2(int oid) throws FileNotFoundException, IOException, SQLException
	{
		System.out.println("Test 2 Reading a large object and save as a file\n");

		// Now open the large object
		System.out.println("Opening large object " + oid);
		LargeObject obj = lobj.open(oid, LargeObjectManager.READ);
		DriverManager.println("got obj=" + obj);

		// Now open a test file - this class will do
		System.out.println("Opening test destination object");
		FileOutputStream fos = new FileOutputStream("blob_testoutput");

		// copy the data
		System.out.println("Copying large object to file");
		byte buf[] = new byte[512];
		int s = obj.size();
		int tl = 0;
		while (s > 0)
		{
			int rs = buf.length;
			if (s < rs)
				rs = s;
			obj.read(buf, 0, rs);
			fos.write(buf, 0, rs);
			tl += rs;
			s -= rs;
		}
		DriverManager.println("Copied " + tl + "/" + obj.size() + " bytes");

		// Close the object
		System.out.println("Closing object");
		obj.close();
	}

	private void ownapi_test3(int oid) throws SQLException
	{
		System.out.println("Test 3 Deleting a large object\n");

		// Now open the large object
		System.out.println("Deleting large object " + oid);
		lobj.unlink(oid);
	}

	// This tests the Blob interface of the JDBC 2.0 specification
	public void jdbc2api(int oid) throws SQLException, IOException
	{
		System.out.println("Testing JDBC2 Blob interface:");
		jdbc2api_cleanup();

		System.out.println("Creating Blob on large object " + oid);
		s.executeUpdate("create table basic (a oid)");

		System.out.println("Inserting row");
		s.executeUpdate("insert into basic values (" + oid + ")");

		System.out.println("Selecting row");
		ResultSet rs = s.executeQuery("select a from basic");
		if (rs != null)
		{
			while (rs.next())
			{
				System.out.println("Fetching Blob");
				Blob b = rs.getBlob("a");
				System.out.println("Blob.length() = " + b.length());
				System.out.println("Characters 400-500:");
				System.out.write(b.getBytes(400l, 100));
				System.out.println();
			}
			rs.close();
		}

		System.out.println("Cleaning up");
		jdbc2api_cleanup();
	}

	private void jdbc2api_cleanup() throws SQLException
	{
		db.setAutoCommit(true);
		try
		{
			s.executeUpdate("drop table basic");
		}
		catch (Exception ex)
		{
			// We ignore any errors here
		}
		db.setAutoCommit(false);
	}

	public static void instructions()
	{
		System.err.println("java example.blobtest jdbc-url user password [debug]");
		System.err.println("\nExamples:\n");
		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");
		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");

		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.");
	}

	public static void main(String args[])
	{
		System.out.println("PostgreSQL blobtest v7.0 rev 1\n");

		if (args.length < 3)
		{
			instructions();
			System.exit(1);
		}

		// This line outputs debug information to stderr. To enable this, simply
		// add an extra parameter to the command line
		if (args.length > 3)
			DriverManager.setLogStream(System.err);

		// Now run the tests
		try
		{
			blobtest test = new blobtest(args);
		}
		catch (Exception ex)
		{
			System.err.println("Exception caught.\n" + ex);
			ex.printStackTrace();
		}
	}
}