1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2.command.ddl; |
7 | |
8 | import java.util.ArrayList; |
9 | |
10 | import org.h2.api.ErrorCode; |
11 | import org.h2.command.CommandInterface; |
12 | import org.h2.constraint.ConstraintReferential; |
13 | import org.h2.engine.Database; |
14 | import org.h2.engine.Right; |
15 | import org.h2.engine.Session; |
16 | import org.h2.message.DbException; |
17 | import org.h2.schema.Schema; |
18 | import org.h2.table.Table; |
19 | import org.h2.table.TableView; |
20 | import org.h2.util.StatementBuilder; |
21 | |
22 | /** |
23 | * This class represents the statement |
24 | * DROP TABLE |
25 | */ |
26 | public class DropTable extends SchemaCommand { |
27 | |
28 | private boolean ifExists; |
29 | private String tableName; |
30 | private Table table; |
31 | private DropTable next; |
32 | private int dropAction; |
33 | |
34 | public DropTable(Session session, Schema schema) { |
35 | super(session, schema); |
36 | dropAction = session.getDatabase().getSettings().dropRestrict ? |
37 | ConstraintReferential.RESTRICT : |
38 | ConstraintReferential.CASCADE; |
39 | } |
40 | |
41 | /** |
42 | * Chain another drop table statement to this statement. |
43 | * |
44 | * @param drop the statement to add |
45 | */ |
46 | public void addNextDropTable(DropTable drop) { |
47 | if (next == null) { |
48 | next = drop; |
49 | } else { |
50 | next.addNextDropTable(drop); |
51 | } |
52 | } |
53 | |
54 | public void setIfExists(boolean b) { |
55 | ifExists = b; |
56 | if (next != null) { |
57 | next.setIfExists(b); |
58 | } |
59 | } |
60 | |
61 | public void setTableName(String tableName) { |
62 | this.tableName = tableName; |
63 | } |
64 | |
65 | private void prepareDrop() { |
66 | table = getSchema().findTableOrView(session, tableName); |
67 | if (table == null) { |
68 | if (!ifExists) { |
69 | throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName); |
70 | } |
71 | } else { |
72 | session.getUser().checkRight(table, Right.ALL); |
73 | if (!table.canDrop()) { |
74 | throw DbException.get(ErrorCode.CANNOT_DROP_TABLE_1, tableName); |
75 | } |
76 | if (dropAction == ConstraintReferential.RESTRICT) { |
77 | ArrayList<TableView> views = table.getViews(); |
78 | if (views != null && views.size() > 0) { |
79 | StatementBuilder buff = new StatementBuilder(); |
80 | for (TableView v : views) { |
81 | buff.appendExceptFirst(", "); |
82 | buff.append(v.getName()); |
83 | } |
84 | throw DbException.get(ErrorCode.CANNOT_DROP_2, tableName, buff.toString()); |
85 | } |
86 | } |
87 | table.lock(session, true, true); |
88 | } |
89 | if (next != null) { |
90 | next.prepareDrop(); |
91 | } |
92 | } |
93 | |
94 | private void executeDrop() { |
95 | // need to get the table again, because it may be dropped already |
96 | // meanwhile (dependent object, or same object) |
97 | table = getSchema().findTableOrView(session, tableName); |
98 | |
99 | if (table != null) { |
100 | table.setModified(); |
101 | Database db = session.getDatabase(); |
102 | db.lockMeta(session); |
103 | db.removeSchemaObject(session, table); |
104 | } |
105 | if (next != null) { |
106 | next.executeDrop(); |
107 | } |
108 | } |
109 | |
110 | @Override |
111 | public int update() { |
112 | session.commit(true); |
113 | prepareDrop(); |
114 | executeDrop(); |
115 | return 0; |
116 | } |
117 | |
118 | public void setDropAction(int dropAction) { |
119 | this.dropAction = dropAction; |
120 | if (next != null) { |
121 | next.setDropAction(dropAction); |
122 | } |
123 | } |
124 | |
125 | @Override |
126 | public int getType() { |
127 | return CommandInterface.DROP_TABLE; |
128 | } |
129 | |
130 | } |