1/*-
2 * Copyright (c) 2002,2008 Oracle.  All rights reserved.
3 *
4 * $Id: second.javas,v 10.8 2008/01/08 20:58:22 bostic Exp $
5 */
6package db;
7
8import com.sleepycat.db.*;
9import java.io.File;
10import java.io.FileNotFoundException;
11import java.io.InputStreamReader;
12import java.io.IOException;
13import java.io.PrintStream;
14
15class SecondaryExample
16{
17	private static final String progname = "SecondaryExample";
18	private static final String DATABASE_HOME = "TESTDIR";
19
20	public static void main(String[] args)
21	{
22		try {
23			SecondaryExample app = new SecondaryExample();
24			app.run();
25		} catch(Exception e) {
26			System.err.println(progname + ": " + e);
27			e.printStackTrace(System.err);
28			System.exit(1);
29		}
30	}
31
32	void run() throws DbException, FileNotFoundException
33	{
34		DbEnv dbenv = new DbEnv(0);
35
36		/* Open the environment. */
37		dbenv.open(DATABASE_HOME,
38		    Db.DB_CREATE | Db.DB_INIT_LOCK | Db.DB_INIT_LOG |
39		    Db.DB_INIT_MPOOL | Db.DB_INIT_TXN, 0);
40
41		try {
42			run_app(dbenv);
43		} finally {
44			dbenv.close(0);
45		}
46	}
47
48	private void run_app(DbEnv dbenv)
49		throws DbException, FileNotFoundException
50	{
51		Db dbp, sdbp;
52		Dbt key, pkey, skey, data;
53		StudentRecord srec;
54
55		/* Open/create primary */
56		dbp = new Db(dbenv, 0);
57		dbp.open(null, "students.db", null, Db.DB_BTREE, Db.DB_CREATE,
58		    0600);
59
60		/*
61		 * Open/create secondary.  Note that it supports duplicate data
62		 * items, since last names might not be unique.
63		 */
64		sdbp = new Db(dbenv, 0);
65		sdbp.set_flags(Db.DB_DUP | Db.DB_DUPSORT);
66		sdbp.open(null, "lastname.db", null, Db.DB_BTREE, Db.DB_CREATE,
67		    0600);
68
69		try {
70			/* Associate the secondary with the primary. */
71			dbp.associate(sdbp, new GetName(), 0);
72
73			/* Add a new record */
74			key = new Dbt();
75			key.set_data("WC42".getBytes());
76			key.set_size(4);
77			srec = new StudentRecord();
78			srec.student_id = "WC42";
79			srec.last_name = "Churchill      ";
80			srec.first_name = "Winston        ";
81			data = new Dbt();
82			srec.encode(data);
83
84			System.out.println("Adding a record with primary key " +
85			    new String(key.get_data()) + " and secondary key " +
86			    srec.last_name);
87			dbp.put(null, key, data, 0);
88
89			/* Now do a lookup */
90			skey = new Dbt();
91			pkey = new Dbt();
92			data = new Dbt();
93			skey.set_data("Churchill      ".getBytes());
94			skey.set_size(15);
95			System.out.println("Searching with secondary key " +
96			    new String(skey.get_data()));
97			sdbp.pget(null, skey, pkey, data, 0);
98
99			System.out.println("Found a record with primary key " +
100			    new String(pkey.get_data()));
101		} finally {
102			dbp.close(0);
103			sdbp.close(0);
104		}
105	}
106
107	/*
108	 * getname -- extracts a secondary key (the last name) from a primary
109	 * 	key/data pair
110	 */
111	class GetName implements DbSecondaryKeyCreate {
112		public int secondary_key_create(Db secondary,
113		    Dbt pkey, Dbt pdata, Dbt skey) {
114 			StudentRecord srec = new StudentRecord();
115			srec.decode(pdata);
116
117			// Make a fixed-length array of last_name
118			byte[] last_name_data = srec.last_name.getBytes();
119			byte[] last_name_raw = new byte[15];
120			System.arraycopy(last_name_data, 0, last_name_raw, 0,
121			    last_name_data.length);
122
123			skey.set_data(last_name_raw);
124			skey.set_size(last_name_raw.length);
125			return (0);
126		}
127	}
128
129	class StudentRecord
130	{
131		String student_id;	// assumed to be 4 bytes long
132		String last_name;	// assumed to be 15 bytes long
133		String first_name;	// assumed to be 15 bytes long
134
135		void decode(Dbt dbt) {
136			byte[] data = dbt.get_data();
137			student_id = new String(data, 0, 4);
138			last_name = new String(data, 4, 15);
139			first_name = new String(data, 19, 15);
140		}
141
142		void encode(Dbt dbt) {
143			byte[] data = new byte[34];
144			System.arraycopy(student_id.getBytes(), 0, data, 0, 4);
145			byte[] last_name_raw = last_name.getBytes();
146			System.arraycopy(last_name_raw, 0, data, 4,
147			    last_name_raw.length);
148			byte[] first_name_raw = first_name.getBytes();
149			System.arraycopy(first_name_raw, 0, data, 19,
150			    first_name_raw.length);
151			dbt.set_data(data);
152			dbt.set_size(data.length);
153		}
154	}
155}
156