File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\schema\Schema.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.schema;
8
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import org.h2.api.TableEngine;
13 import org.h2.command.ddl.CreateTableData;
14 import org.h2.constant.ErrorCode;
15 import org.h2.constant.SysProperties;
16 import org.h2.constraint.Constraint;
17 import org.h2.engine.Database;
18 import org.h2.engine.DbObject;
19 import org.h2.engine.DbObjectBase;
20 import org.h2.engine.FunctionAlias;
21 import org.h2.engine.Session;
22 import org.h2.engine.User;
23 import org.h2.index.Index;
24 import org.h2.message.DbException;
25 import org.h2.message.Trace;
26 import org.h2.table.RegularTable;
27 import org.h2.table.Table;
28 import org.h2.table.TableLink;
29 import org.h2.util.New;
30 import org.h2.util.Utils;
31
32 /**
33 * A schema as created by the SQL statement
34 * CREATE SCHEMA
35 */
36 public class Schema extends DbObjectBase {
37
38 private User owner;
39 private final boolean system;
40
41 private final HashMap<String, Table> tablesAndViews;
42 private final HashMap<String, Index> indexes;
43 private final HashMap<String, Sequence> sequences;
44 private final HashMap<String, TriggerObject> triggers;
45 private final HashMap<String, Constraint> constraints;
46 private final HashMap<String, Constant> constants;
47 private final HashMap<String, FunctionAlias> functions;
48
49 /**
50 * The set of returned unique names that are not yet stored. It is used to
51 * avoid returning the same unique name twice when multiple threads
52 * concurrently create objects.
53 */
54 private final HashSet<String> temporaryUniqueNames = New.hashSet();
55
56 /**
57 * Create a new schema object.
58 *
59 * @param database the database
60 * @param id the object id
61 * @param schemaName the schema name
62 * @param owner the owner of the schema
63 * @param system if this is a system schema (such a schema can not be
64 * dropped)
65 */
66 public Schema(Database database, int id, String schemaName, User owner, boolean system) {
67 tablesAndViews = database.newStringMap();
68 indexes = database.newStringMap();
69 sequences = database.newStringMap();
70 triggers = database.newStringMap();
71 constraints = database.newStringMap();
72 constants = database.newStringMap();
73 functions = database.newStringMap();
74 initDbObjectBase(database, id, schemaName, Trace.SCHEMA);
75 this.owner = owner;
76 this.system = system;
77 }
78
79 /**
80 * Check if this schema can be dropped. System schemas can not be dropped.
81 *
82 * @return true if it can be dropped
83 */
84 public boolean canDrop() {
85 return !system;
86 }
87
88 public String getCreateSQLForCopy(Table table, String quotedName) {
89 throw DbException.throwInternalError();
90 }
91
92 public String getDropSQL() {
93 return null;
94 }
95
96 public String getCreateSQL() {
97 if (system) {
98 return null;
99 }
100 return "CREATE SCHEMA IF NOT EXISTS " +
101 getSQL() + " AUTHORIZATION " + owner.getSQL();
102 }
103
104 public int getType() {
105 return DbObject.SCHEMA;
106 }
107
108 public void removeChildrenAndResources(Session session) {
109 while (triggers != null && triggers.size() > 0) {
110 TriggerObject obj = (TriggerObject) triggers.values().toArray()[0];
111 database.removeSchemaObject(session, obj);
112 }
113 while (constraints != null && constraints.size() > 0) {
114 Constraint obj = (Constraint) constraints.values().toArray()[0];
115 database.removeSchemaObject(session, obj);
116 }
117 while (tablesAndViews != null && tablesAndViews.size() > 0) {
118 Table obj = (Table) tablesAndViews.values().toArray()[0];
119 database.removeSchemaObject(session, obj);
120 }
121 while (indexes != null && indexes.size() > 0) {
122 Index obj = (Index) indexes.values().toArray()[0];
123 database.removeSchemaObject(session, obj);
124 }
125 while (sequences != null && sequences.size() > 0) {
126 Sequence obj = (Sequence) sequences.values().toArray()[0];
127 database.removeSchemaObject(session, obj);
128 }
129 while (constants != null && constants.size() > 0) {
130 Constant obj = (Constant) constants.values().toArray()[0];
131 database.removeSchemaObject(session, obj);
132 }
133 while (functions != null && functions.size() > 0) {
134 FunctionAlias obj = (FunctionAlias) functions.values().toArray()[0];
135 database.removeSchemaObject(session, obj);
136 }
137 database.removeMeta(session, getId());
138 owner = null;
139 invalidate();
140 }
141
142 public void checkRename() {
143 // ok
144 }
145
146 /**
147 * Get the owner of this schema.
148 *
149 * @return the owner
150 */
151 public User getOwner() {
152 return owner;
153 }
154
155 @SuppressWarnings("unchecked")
156 private HashMap<String, SchemaObject> getMap(int type) {
157 HashMap<String, ? extends SchemaObject> result;
158 switch (type) {
159 case DbObject.TABLE_OR_VIEW:
160 result = tablesAndViews;
161 break;
162 case DbObject.SEQUENCE:
163 result = sequences;
164 break;
165 case DbObject.INDEX:
166 result = indexes;
167 break;
168 case DbObject.TRIGGER:
169 result = triggers;
170 break;
171 case DbObject.CONSTRAINT:
172 result = constraints;
173 break;
174 case DbObject.CONSTANT:
175 result = constants;
176 break;
177 case DbObject.FUNCTION_ALIAS:
178 result = functions;
179 break;
180 default:
181 throw DbException.throwInternalError("type=" + type);
182 }
183 return (HashMap<String, SchemaObject>) result;
184 }
185
186 /**
187 * Add an object to this schema.
188 * This method must not be called within CreateSchemaObject;
189 * use Database.addSchemaObject() instead
190 *
191 * @param obj the object to add
192 */
193 public void add(SchemaObject obj) {
194 if (SysProperties.CHECK && obj.getSchema() != this) {
195 DbException.throwInternalError("wrong schema");
196 }
197 String name = obj.getName();
198 HashMap<String, SchemaObject> map = getMap(obj.getType());
199 if (SysProperties.CHECK && map.get(name) != null) {
200 DbException.throwInternalError("object already exists: " + name);
201 }
202 map.put(name, obj);
203 freeUniqueName(name);
204 }
205
206 /**
207 * Rename an object.
208 *
209 * @param obj the object to rename
210 * @param newName the new name
211 */
212 public void rename(SchemaObject obj, String newName) {
213 int type = obj.getType();
214 HashMap<String, SchemaObject> map = getMap(type);
215 if (SysProperties.CHECK) {
216 if (!map.containsKey(obj.getName())) {
217 DbException.throwInternalError("not found: " + obj.getName());
218 }
219 if (obj.getName().equals(newName) || map.containsKey(newName)) {
220 DbException.throwInternalError("object already exists: " + newName);
221 }
222 }
223 obj.checkRename();
224 map.remove(obj.getName());
225 freeUniqueName(obj.getName());
226 obj.rename(newName);
227 map.put(newName, obj);
228 freeUniqueName(newName);
229 }
230
231 /**
232 * Try to find a table or view with this name. This method returns null if
233 * no object with this name exists. Local temporary tables are also
234 * returned.
235 *
236 * @param session the session
237 * @param name the object name
238 * @return the object or null
239 */
240 public Table findTableOrView(Session session, String name) {
241 Table table = tablesAndViews.get(name);
242 if (table == null && session != null) {
243 table = session.findLocalTempTable(name);
244 }
245 return table;
246 }
247
248 /**
249 * Try to find an index with this name. This method returns null if
250 * no object with this name exists.
251 *
252 * @param session the session
253 * @param name the object name
254 * @return the object or null
255 */
256 public Index findIndex(Session session, String name) {
257 Index index = indexes.get(name);
258 if (index == null) {
259 index = session.findLocalTempTableIndex(name);
260 }
261 return index;
262 }
263
264 /**
265 * Try to find a trigger with this name. This method returns null if
266 * no object with this name exists.
267 *
268 * @param name the object name
269 * @return the object or null
270 */
271 public TriggerObject findTrigger(String name) {
272 return triggers.get(name);
273 }
274
275 /**
276 * Try to find a sequence with this name. This method returns null if
277 * no object with this name exists.
278 *
279 * @param sequenceName the object name
280 * @return the object or null
281 */
282 public Sequence findSequence(String sequenceName) {
283 return sequences.get(sequenceName);
284 }
285
286 /**
287 * Try to find a constraint with this name. This method returns null if no
288 * object with this name exists.
289 *
290 * @param session the session
291 * @param name the object name
292 * @return the object or null
293 */
294 public Constraint findConstraint(Session session, String name) {
295 Constraint constraint = constraints.get(name);
296 if (constraint == null) {
297 constraint = session.findLocalTempTableConstraint(name);
298 }
299 return constraint;
300 }
301
302 /**
303 * Try to find a user defined constant with this name. This method returns
304 * null if no object with this name exists.
305 *
306 * @param constantName the object name
307 * @return the object or null
308 */
309 public Constant findConstant(String constantName) {
310 return constants.get(constantName);
311 }
312
313 /**
314 * Try to find a user defined function with this name. This method returns
315 * null if no object with this name exists.
316 *
317 * @param functionAlias the object name
318 * @return the object or null
319 */
320 public FunctionAlias findFunction(String functionAlias) {
321 return functions.get(functionAlias);
322 }
323
324 /**
325 * Release a unique object name.
326 *
327 * @param name the object name
328 */
329 public void freeUniqueName(String name) {
330 if (name != null) {
331 synchronized (temporaryUniqueNames) {
332 temporaryUniqueNames.remove(name);
333 }
334 }
335 }
336
337 private String getUniqueName(DbObject obj, HashMap<String, ? extends SchemaObject> map, String prefix) {
338 String hash = Integer.toHexString(obj.getName().hashCode()).toUpperCase();
339 String name = null;
340 synchronized (temporaryUniqueNames) {
341 for (int i = 1, len = hash.length(); i < len; i++) {
342 name = prefix + hash.substring(0, i);
343 if (!map.containsKey(name) && !temporaryUniqueNames.contains(name)) {
344 break;
345 }
346 name = null;
347 }
348 if (name == null) {
349 prefix = prefix + hash + "_";
350 for (int i = 0;; i++) {
351 name = prefix + i;
352 if (!map.containsKey(name) && !temporaryUniqueNames.contains(name)) {
353 break;
354 }
355 }
356 }
357 temporaryUniqueNames.add(name);
358 }
359 return name;
360 }
361
362 /**
363 * Create a unique constraint name.
364 *
365 * @param session the session
366 * @param table the constraint table
367 * @return the unique name
368 */
369 public String getUniqueConstraintName(Session session, Table table) {
370 HashMap<String, Constraint> tableConstraints;
371 if (table.isTemporary() && !table.isGlobalTemporary()) {
372 tableConstraints = session.getLocalTempTableConstraints();
373 } else {
374 tableConstraints = constraints;
375 }
376 return getUniqueName(table, tableConstraints, "CONSTRAINT_");
377 }
378
379 /**
380 * Create a unique index name.
381 *
382 * @param session the session
383 * @param table the indexed table
384 * @param prefix the index name prefix
385 * @return the unique name
386 */
387 public String getUniqueIndexName(Session session, Table table, String prefix) {
388 HashMap<String, Index> tableIndexes;
389 if (table.isTemporary() && !table.isGlobalTemporary()) {
390 tableIndexes = session.getLocalTempTableIndexes();
391 } else {
392 tableIndexes = indexes;
393 }
394 return getUniqueName(table, tableIndexes, prefix);
395 }
396
397 /**
398 * Get the table or view with the given name.
399 * Local temporary tables are also returned.
400 *
401 * @param session the session
402 * @param name the table or view name
403 * @return the table or view
404 * @throws DbException if no such object exists
405 */
406 public Table getTableOrView(Session session, String name) {
407 Table table = tablesAndViews.get(name);
408 if (table == null) {
409 if (session != null) {
410 table = session.findLocalTempTable(name);
411 }
412 if (table == null) {
413 throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, name);
414 }
415 }
416 return table;
417 }
418
419 /**
420 * Get the index with the given name.
421 *
422 * @param name the index name
423 * @return the index
424 * @throws DbException if no such object exists
425 */
426 public Index getIndex(String name) {
427 Index index = indexes.get(name);
428 if (index == null) {
429 throw DbException.get(ErrorCode.INDEX_NOT_FOUND_1, name);
430 }
431 return index;
432 }
433
434 /**
435 * Get the constraint with the given name.
436 *
437 * @param name the constraint name
438 * @return the constraint
439 * @throws DbException if no such object exists
440 */
441 public Constraint getConstraint(String name) {
442 Constraint constraint = constraints.get(name);
443 if (constraint == null) {
444 throw DbException.get(ErrorCode.CONSTRAINT_NOT_FOUND_1, name);
445 }
446 return constraint;
447 }
448
449 /**
450 * Get the user defined constant with the given name.
451 *
452 * @param constantName the constant name
453 * @return the constant
454 * @throws DbException if no such object exists
455 */
456 public Constant getConstant(String constantName) {
457 Constant constant = constants.get(constantName);
458 if (constant == null) {
459 throw DbException.get(ErrorCode.CONSTANT_NOT_FOUND_1, constantName);
460 }
461 return constant;
462 }
463
464 /**
465 * Get the sequence with the given name.
466 *
467 * @param sequenceName the sequence name
468 * @return the sequence
469 * @throws DbException if no such object exists
470 */
471 public Sequence getSequence(String sequenceName) {
472 Sequence sequence = sequences.get(sequenceName);
473 if (sequence == null) {
474 throw DbException.get(ErrorCode.SEQUENCE_NOT_FOUND_1, sequenceName);
475 }
476 return sequence;
477 }
478
479 /**
480 * Get all objects.
481 *
482 * @return a (possible empty) list of all objects
483 */
484 public ArrayList<SchemaObject> getAll() {
485 ArrayList<SchemaObject> all = New.arrayList();
486 all.addAll(getMap(DbObject.TABLE_OR_VIEW).values());
487 all.addAll(getMap(DbObject.SEQUENCE).values());
488 all.addAll(getMap(DbObject.INDEX).values());
489 all.addAll(getMap(DbObject.TRIGGER).values());
490 all.addAll(getMap(DbObject.CONSTRAINT).values());
491 all.addAll(getMap(DbObject.CONSTANT).values());
492 all.addAll(getMap(DbObject.FUNCTION_ALIAS).values());
493 return all;
494 }
495
496 /**
497 * Get all objects of the given type.
498 *
499 * @param type the object type
500 * @return a (possible empty) list of all objects
501 */
502 public ArrayList<SchemaObject> getAll(int type) {
503 HashMap<String, SchemaObject> map = getMap(type);
504 return New.arrayList(map.values());
505 }
506
507 /**
508 * Get all tables and views.
509 *
510 * @return a (possible empty) list of all objects
511 */
512 public ArrayList<Table> getAllTablesAndViews() {
513 synchronized (database) {
514 return New.arrayList(tablesAndViews.values());
515 }
516 }
517
518 /**
519 * Remove an object from this schema.
520 *
521 * @param obj the object to remove
522 */
523 public void remove(SchemaObject obj) {
524 String objName = obj.getName();
525 HashMap<String, SchemaObject> map = getMap(obj.getType());
526 if (SysProperties.CHECK && !map.containsKey(objName)) {
527 DbException.throwInternalError("not found: " + objName);
528 }
529 map.remove(objName);
530 freeUniqueName(objName);
531 }
532
533 /**
534 * Add a table to the schema.
535 *
536 * @param data the create table information
537 * @return the created {@link Table} object
538 */
539 public Table createTable(CreateTableData data) {
540 synchronized (database) {
541 if (!data.temporary || data.globalTemporary) {
542 database.lockMeta(data.session);
543 }
544 data.schema = this;
545 if (data.tableEngine != null) {
546 TableEngine engine;
547 try {
548 engine = (TableEngine) Utils.loadUserClass(data.tableEngine).newInstance();
549 } catch (Exception e) {
550 throw DbException.convert(e);
551 }
552 return engine.createTable(data);
553 }
554 return new RegularTable(data);
555 }
556 }
557
558 /**
559 * Add a linked table to the schema.
560 *
561 * @param id the object id
562 * @param tableName the table name of the alias
563 * @param driver the driver class name
564 * @param url the database URL
565 * @param user the user name
566 * @param password the password
567 * @param originalSchema the schema name of the target table
568 * @param originalTable the table name of the target table
569 * @param emitUpdates if updates should be emitted instead of delete/insert
570 * @param force create the object even if the database can not be accessed
571 * @return the {@link TableLink} object
572 */
573 public TableLink createTableLink(int id, String tableName,
574 String driver, String url, String user, String password,
575 String originalSchema, String originalTable, boolean emitUpdates, boolean force) {
576 synchronized (database) {
577 return new TableLink(this, id, tableName,
578 driver, url, user, password,
579 originalSchema, originalTable, emitUpdates, force);
580 }
581 }
582
583 }
584