KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > command > dml > Script


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.command.dml;
6
7 import java.io.FileInputStream JavaDoc;
8 import java.io.FileOutputStream JavaDoc;
9 import java.io.FileReader JavaDoc;
10 import java.io.FileWriter JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.io.InputStream JavaDoc;
13 import java.io.Reader JavaDoc;
14 import java.sql.Connection JavaDoc;
15 import java.sql.ResultSet JavaDoc;
16 import java.sql.SQLException JavaDoc;
17 import java.sql.Statement JavaDoc;
18 import java.util.Comparator JavaDoc;
19
20 import org.h2.command.Parser;
21 import org.h2.constraint.Constraint;
22 import org.h2.engine.Comment;
23 import org.h2.engine.Constants;
24 import org.h2.engine.Database;
25 import org.h2.engine.DbObject;
26 import org.h2.engine.FunctionAlias;
27 import org.h2.engine.Right;
28 import org.h2.engine.Role;
29 import org.h2.engine.Session;
30 import org.h2.engine.Setting;
31 import org.h2.engine.User;
32 import org.h2.engine.UserDataType;
33 import org.h2.expression.ExpressionColumn;
34 import org.h2.index.Cursor;
35 import org.h2.index.Index;
36 import org.h2.message.Message;
37 import org.h2.result.LocalResult;
38 import org.h2.result.Row;
39 import org.h2.schema.Constant;
40 import org.h2.schema.Schema;
41 import org.h2.schema.Sequence;
42 import org.h2.schema.TriggerObject;
43 import org.h2.table.Column;
44 import org.h2.table.PlanItem;
45 import org.h2.table.Table;
46 import org.h2.util.ByteUtils;
47 import org.h2.util.FileUtils;
48 import org.h2.util.IOUtils;
49 import org.h2.util.MathUtils;
50 import org.h2.util.ObjectArray;
51 import org.h2.util.StringUtils;
52 import org.h2.value.Value;
53 import org.h2.value.ValueLob;
54 import org.h2.value.ValueString;
55
56 public class Script extends ScriptBase {
57
58     private boolean passwords;
59     private boolean data;
60     private boolean settings;
61     private boolean drop;
62     private LocalResult result;
63     private byte[] lineSeparator;
64     private byte[] buffer;
65     private boolean tempLobTableCreated;
66     private int nextLobId;
67     private int lobBlockSize = Integer.MAX_VALUE;
68     private static final String JavaDoc TEMP_LOB_FILENAME = "system_temp_lob.db";
69
70     public Script(Session session) {
71         super(session);
72     }
73
74     public boolean isQuery() {
75         return true;
76     }
77     
78     // TODO lock all tables for 'script' command
79

80     public void setData(boolean data) {
81         this.data = data;
82     }
83
84     public void setPasswords(boolean passwords) {
85         this.passwords = passwords;
86     }
87
88     public void setSettings(boolean settings) {
89         this.settings = settings;
90     }
91     
92     public void setLobBlockSize(long blockSize) {
93         this.lobBlockSize = MathUtils.convertLongToInt(blockSize);
94     }
95     
96     public void setDrop(boolean drop) {
97         this.drop = drop;
98     }
99
100     public LocalResult query(int maxrows) throws SQLException JavaDoc {
101         session.getUser().checkAdmin();
102         reset();
103         try {
104             ObjectArray cols = new ObjectArray();
105             cols.add(new ExpressionColumn(session.getDatabase(), null, new Column("SCRIPT", Value.STRING, 0, 0)));
106             result = new LocalResult(session, cols, 1);
107             deleteStore();
108             openOutput();
109             if(out != null) {
110                 buffer = new byte[Constants.IO_BUFFER_SIZE];
111             }
112             Database db = session.getDatabase();
113             if(settings) {
114                 ObjectArray settings = db.getAllSettings();
115                 for(int i=0; i<settings.size(); i++) {
116                     Setting setting = (Setting) settings.get(i);
117                     add(setting.getCreateSQL(), false);
118                 }
119             }
120             if(out != null) {
121                 add("", true);
122             }
123             ObjectArray users = db.getAllUsers();
124             for(int i=0; i<users.size(); i++) {
125                 User user = (User) users.get(i);
126                 add(user.getCreateSQL(passwords, true), false);
127             }
128             ObjectArray roles = db.getAllRoles();
129             for(int i=0; i<roles.size(); i++) {
130                 Role role = (Role) roles.get(i);
131                 add(role.getCreateSQL(), false);
132             }
133             ObjectArray schemas = db.getAllSchemas();
134             for(int i=0; i<schemas.size(); i++) {
135                 Schema schema = (Schema) schemas.get(i);
136                 add(schema.getCreateSQL(), false);
137             }
138             ObjectArray datatypes = db.getAllUserDataTypes();
139             for(int i=0; i<datatypes.size(); i++) {
140                 UserDataType datatype = (UserDataType) datatypes.get(i);
141                 add(datatype.getCreateSQL(), false);
142             }
143             ObjectArray constants = db.getAllSchemaObjects(DbObject.CONSTANT);
144             for(int i=0; i<constants.size(); i++) {
145                 Constant constant = (Constant) constants.get(i);
146                 add(constant.getCreateSQL(), false);
147             }
148             ObjectArray functionAliases = db.getAllFunctionAliases();
149             for(int i=0; i<functionAliases.size(); i++) {
150                 FunctionAlias alias = (FunctionAlias) functionAliases.get(i);
151                 add(alias.getCreateSQL(), false);
152             }
153             ObjectArray tables = db.getAllSchemaObjects(DbObject.TABLE_OR_VIEW);
154             // sort by id, so that views are after tables and views on views after the base views
155
tables.sort(new Comparator JavaDoc() {
156                 public int compare(Object JavaDoc o1, Object JavaDoc o2) {
157                     Table t1 = (Table)o1;
158                     Table t2 = (Table)o2;
159                     return t1.getId() - t2.getId();
160                 }
161             });
162             for(int i=0; i<tables.size(); i++) {
163                 Table table = (Table) tables.get(i);
164                 table.lock(session, false);
165                 String JavaDoc sql = table.getCreateSQL();
166                 if(sql == null) {
167                     // null for metadata tables
168
continue;
169                 }
170                 String JavaDoc tableType = table.getTableType();
171                 if(drop) {
172                     if(Table.VIEW.equals(tableType)) {
173                         add("DROP VIEW IF EXISTS " + table.getSQL(), false);
174                     } else {
175                         add("DROP TABLE IF EXISTS " + table.getSQL(), false);
176                     }
177                 }
178             }
179             ObjectArray sequences = db.getAllSchemaObjects(DbObject.SEQUENCE);
180             for(int i=0; i<sequences.size(); i++) {
181                 Sequence sequence = (Sequence) sequences.get(i);
182                 if(drop && !sequence.getBelongsToTable()) {
183                     add("DROP SEQUENCE IF EXISTS " + sequence.getSQL(), false);
184                 }
185                 add(sequence.getCreateSQL(), false);
186             }
187             for(int i=0; i<tables.size(); i++) {
188                 Table table = (Table) tables.get(i);
189                 table.lock(session, false);
190                 String JavaDoc sql = table.getCreateSQL();
191                 if(sql == null) {
192                     // null for metadata tables
193
continue;
194                 }
195                 String JavaDoc tableType = table.getTableType();
196                 add(sql, false);
197                 if(Table.TABLE.equals(tableType)) {
198                     if(table.canGetRowCount()) {
199                         String JavaDoc rowcount = "-- " + table.getRowCount() + " = SELECT COUNT(*) FROM " + table.getSQL();
200                         add(rowcount, false);
201                     }
202                     if(data) {
203                         PlanItem plan = table.getBestPlanItem(session, null);
204                         Index index = plan.getIndex();
205                         Cursor cursor = index.find(session, null, null);
206                         Column[] columns = table.getColumns();
207                         String JavaDoc ins = "INSERT INTO " + table.getSQL() + "(";
208                         for(int j=0; j<columns.length; j++) {
209                             if(j>0) {
210                                 ins += ", ";
211                             }
212                             ins += Parser.quoteIdentifier(columns[j].getName());
213                         }
214                         ins += ") VALUES(";
215                         while(cursor.next()) {
216                             Row row = cursor.get();
217                             String JavaDoc s = ins;
218                             for(int j=0; j<row.getColumnCount(); j++) {
219                                 if(j>0) {
220                                     s += ", ";
221                                 }
222                                 Value v = row.getValue(j);
223                                 if(v.getPrecision() > lobBlockSize) {
224                                     int id;
225                                     if(v.getType() == Value.CLOB) {
226                                         id = writeLobStream((ValueLob)v);
227                                         s += "SYSTEM_COMBINE_CLOB("+id+")";
228                                     } else if(v.getType() == Value.BLOB) {
229                                         id = writeLobStream((ValueLob)v);
230                                         s += "SYSTEM_COMBINE_BLOB("+id+")";
231                                     } else {
232                                         s += v.getSQL();
233                                     }
234                                 } else {
235                                     s += v.getSQL();
236                                 }
237                             }
238                             s += ")";
239                             add(s, true);
240                         }
241                     }
242                 }
243                 ObjectArray indexes = table.getIndexes();
244                 for(int j=0; indexes != null && j<indexes.size(); j++) {
245                     Index index = (Index) indexes.get(j);
246                     if(!index.getIndexType().belongsToConstraint()) {
247                         add(index.getCreateSQL(), false);
248                     }
249                 }
250             }
251             if(tempLobTableCreated) {
252                 add("DROP TABLE IF EXISTS SYSTEM_LOB_STREAM", true);
253                 add("CALL SYSTEM_COMBINE_BLOB(-1)", true);
254                 add("DROP ALIAS IF EXISTS SYSTEM_COMBINE_CLOB", true);
255                 add("DROP ALIAS IF EXISTS SYSTEM_COMBINE_BLOB", true);
256                 tempLobTableCreated = false;
257             }
258             ObjectArray constraints = db.getAllSchemaObjects(DbObject.CONSTRAINT);
259             for(int i=0; i<constraints.size(); i++) {
260                 Constraint constraint = (Constraint) constraints.get(i);
261                 add(constraint.getCreateSQLWithoutIndexes(), false);
262             }
263             ObjectArray triggers = db.getAllSchemaObjects(DbObject.TRIGGER);
264             for(int i=0; i<triggers.size(); i++) {
265                 TriggerObject trigger = (TriggerObject) triggers.get(i);
266                 add(trigger.getCreateSQL(), false);
267             }
268             ObjectArray rights = db.getAllRights();
269             for(int i=0; i<rights.size(); i++) {
270                 Right right = (Right) rights.get(i);
271                 add(right.getCreateSQL(), false);
272             }
273             ObjectArray comments = db.getAllComments();
274             for(int i=0; i<comments.size(); i++) {
275                 Comment comment = (Comment) comments.get(i);
276                 add(comment.getCreateSQL(), false);
277             }
278             closeIO();
279         } catch(IOException JavaDoc e) {
280             throw Message.convert(e);
281         } finally {
282             closeIO();
283         }
284         result.done();
285         LocalResult r = result;
286         reset();
287         return r;
288     }
289     
290     private int writeLobStream(ValueLob v) throws IOException JavaDoc, SQLException JavaDoc {
291         if(!tempLobTableCreated) {
292             add("CREATE TABLE IF NOT EXISTS SYSTEM_LOB_STREAM(ID INT, PART INT, CDATA VARCHAR, BDATA BINARY, PRIMARY KEY(ID, PART))", true);
293             add("CREATE ALIAS IF NOT EXISTS SYSTEM_COMBINE_CLOB FOR \"" + this.getClass().getName() + ".combineClob\"", true);
294             add("CREATE ALIAS IF NOT EXISTS SYSTEM_COMBINE_BLOB FOR \"" + this.getClass().getName() + ".combineBlob\"", true);
295             tempLobTableCreated = true;
296         }
297         int id = nextLobId++;
298         switch(v.getType()) {
299         case Value.BLOB: {
300             byte[] bytes = new byte[lobBlockSize];
301             InputStream JavaDoc in = v.getInputStream();
302             try {
303                 for(int i=0; ; i++) {
304                     StringBuffer JavaDoc buff = new StringBuffer JavaDoc(lobBlockSize * 2);
305                     buff.append("INSERT INTO SYSTEM_LOB_STREAM VALUES(" + id + ", " + i + ", NULL, '");
306                     int len = IOUtils.readFully(in, bytes, lobBlockSize);
307                     if(len < 0) {
308                         break;
309                     }
310                     buff.append(ByteUtils.convertBytesToString(bytes, len));
311                     buff.append("');");
312                     String JavaDoc sql = buff.toString();
313                     add(sql, true);
314                 }
315             } finally {
316                 IOUtils.closeSilently(in);
317             }
318             break;
319         }
320         case Value.CLOB: {
321             char[] chars = new char[lobBlockSize];
322             Reader JavaDoc in = v.getReader();
323             try {
324                 for(int i=0; ; i++) {
325                     StringBuffer JavaDoc buff = new StringBuffer JavaDoc(lobBlockSize * 2);
326                     buff.append("INSERT INTO SYSTEM_LOB_STREAM VALUES(" + id + ", " + i + ", ");
327                     int len = IOUtils.readFully(in, chars, lobBlockSize);
328                     if(len < 0) {
329                         break;
330                     }
331                     buff.append(StringUtils.quoteStringSQL(new String JavaDoc(chars)));
332                     buff.append(", NULL);");
333                     String JavaDoc sql = buff.toString();
334                     add(sql, true);
335                 }
336             } finally {
337                 IOUtils.closeSilently(in);
338             }
339             break;
340         }
341         default:
342             throw Message.getInternalError("type:"+v.getType());
343         }
344         return id;
345     }
346     
347     // called from the script
348
public static InputStream JavaDoc combineBlob(Connection JavaDoc conn, int id) throws SQLException JavaDoc, IOException JavaDoc {
349         if(id < 0) {
350             FileUtils.delete(TEMP_LOB_FILENAME);
351             return null;
352         }
353         Statement JavaDoc stat = conn.createStatement();
354         ResultSet JavaDoc rs = stat.executeQuery("SELECT BDATA FROM SYSTEM_LOB_STREAM WHERE ID=" + id + " ORDER BY PART");
355         FileOutputStream JavaDoc out = new FileOutputStream JavaDoc(TEMP_LOB_FILENAME);
356         while(rs.next()) {
357             InputStream JavaDoc in = rs.getBinaryStream(1);
358             IOUtils.copyAndCloseInput(in, out);
359         }
360         out.close();
361         stat.execute("DELETE FROM SYSTEM_LOB_STREAM WHERE ID=" + id);
362         return new FileInputStream JavaDoc(TEMP_LOB_FILENAME);
363     }
364
365     // called from the script
366
public static Reader JavaDoc combineClob(Connection JavaDoc conn, int id) throws SQLException JavaDoc, IOException JavaDoc {
367         Statement JavaDoc stat = conn.createStatement();
368         ResultSet JavaDoc rs = stat.executeQuery("SELECT CDATA FROM SYSTEM_LOB_STREAM WHERE ID=" + id + " ORDER BY PART");
369         FileWriter JavaDoc out = new FileWriter JavaDoc(TEMP_LOB_FILENAME);
370         while(rs.next()) {
371             Reader JavaDoc in = rs.getCharacterStream(1);
372             IOUtils.copyAndCloseInput(in, out);
373         }
374         out.close();
375         stat.execute("DELETE FROM SYSTEM_LOB_STREAM WHERE ID=" + id);
376         return new FileReader JavaDoc(TEMP_LOB_FILENAME);
377     }
378
379     private void reset() throws SQLException JavaDoc {
380         result = null;
381         buffer = null;
382         lineSeparator = StringUtils.utf8Encode(System.getProperty("line.separator"));
383     }
384
385     private void add(String JavaDoc s, boolean insert) throws SQLException JavaDoc, IOException JavaDoc {
386         if(s==null) {
387             return;
388         }
389         if (out != null) {
390             byte[] buff = StringUtils.utf8Encode(s + ";");
391             int len = MathUtils.roundUp(buff.length + lineSeparator.length, Constants.FILE_BLOCK_SIZE);
392             buffer = ByteUtils.copy(buff, buffer);
393             
394             if(len > buffer.length) {
395                 buffer = new byte[len];
396             }
397             System.arraycopy(buff, 0, buffer, 0, buff.length);
398             for(int i=buff.length; i<len - lineSeparator.length; i++) {
399                 buffer[i] = ' ';
400             }
401             for(int j=0, i=len - lineSeparator.length; i<len; i++, j++) {
402                 buffer[i] = lineSeparator[j];
403             }
404             out.write(buffer, 0, len);
405             if(!insert) {
406                 Value[] row = new Value[1];
407                 row[0] = ValueString.get(s);
408                 result.addRow(row);
409             }
410         } else {
411             Value[] row = new Value[1];
412             row[0] = ValueString.get(s);
413             result.addRow(row);
414         }
415     }
416
417 }
418
Popular Tags