File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\result\ResultTempTable.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.result;
8
9 import java.util.ArrayList;
10 import org.h2.command.ddl.CreateTableData;
11 import org.h2.engine.Constants;
12 import org.h2.engine.Database;
13 import org.h2.engine.Session;
14 import org.h2.index.Cursor;
15 import org.h2.index.Index;
16 import org.h2.index.IndexType;
17 import org.h2.index.PageBtreeIndex;
18 import org.h2.schema.Schema;
19 import org.h2.table.Column;
20 import org.h2.table.IndexColumn;
21 import org.h2.table.RegularTable;
22 import org.h2.value.Value;
23 import org.h2.value.ValueArray;
24
25 /**
26 * This class implements the temp table buffer for the LocalResult class.
27 */
28 public class ResultTempTable implements ResultExternal {
29
30 private static final String COLUMN_NAME = "DATA";
31 private final SortOrder sort;
32 private final Session session;
33 private final Index index;
34 private RegularTable table;
35 private Cursor resultCursor;
36
37 private final ResultTempTable parent;
38 private boolean closed;
39 private int childCount;
40
41 ResultTempTable(Session session, SortOrder sort) {
42 this.session = session;
43 this.sort = sort;
44 Schema schema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN);
45 Column column = new Column(COLUMN_NAME, Value.ARRAY);
46 column.setNullable(false);
47 CreateTableData data = new CreateTableData();
48 data.columns.add(column);
49 data.id = session.getDatabase().allocateObjectId();
50 data.tableName = "TEMP_RESULT_SET_" + data.id;
51 data.temporary = true;
52 data.persistIndexes = false;
53 data.persistData = true;
54 data.create = true;
55 data.session = session;
56 table = (RegularTable) schema.createTable(data);
57 int indexId = session.getDatabase().allocateObjectId();
58 IndexColumn indexColumn = new IndexColumn();
59 indexColumn.column = column;
60 indexColumn.columnName = COLUMN_NAME;
61 IndexType indexType;
62 indexType = IndexType.createPrimaryKey(true, false);
63 IndexColumn[] indexCols = { indexColumn };
64 index = new PageBtreeIndex(table, indexId, data.tableName, indexCols, indexType, true, session);
65 index.setTemporary(true);
66 table.getIndexes().add(index);
67 parent = null;
68 }
69
70 private ResultTempTable(ResultTempTable parent) {
71 this.parent = parent;
72 this.session = parent.session;
73 this.table = parent.table;
74 this.index = parent.index;
75 // sort is only used when adding rows
76 this.sort = null;
77 reset();
78 }
79
80 public synchronized ResultExternal createShallowCopy() {
81 if (parent != null) {
82 return parent.createShallowCopy();
83 }
84 if (closed) {
85 return null;
86 }
87 childCount++;
88 return new ResultTempTable(this);
89 }
90
91 public int removeRow(Value[] values) {
92 Row row = convertToRow(values);
93 Cursor cursor = find(row);
94 if (cursor != null) {
95 row = cursor.get();
96 table.removeRow(session, row);
97 }
98 return (int) table.getRowCount(session);
99 }
100
101 public boolean contains(Value[] values) {
102 return find(convertToRow(values)) != null;
103 }
104
105 public int addRow(Value[] values) {
106 Row row = convertToRow(values);
107 Cursor cursor = find(row);
108 if (cursor == null) {
109 table.addRow(session, row);
110 }
111 return (int) table.getRowCount(session);
112 }
113
114 public int addRows(ArrayList<Value[]> rows) {
115 if (sort != null) {
116 sort.sort(rows);
117 }
118 for (Value[] values : rows) {
119 addRow(values);
120 }
121 return (int) table.getRowCount(session);
122 }
123
124 private synchronized void closeChild() {
125 if (--childCount == 0 && closed) {
126 dropTable();
127 }
128 }
129
130 public synchronized void close() {
131 if (closed) {
132 return;
133 }
134 closed = true;
135 if (parent != null) {
136 parent.closeChild();
137 } else {
138 if (childCount == 0) {
139 dropTable();
140 }
141 }
142 }
143
144 private void dropTable() {
145 if (table == null) {
146 return;
147 }
148 try {
149 table.truncate(session);
150 Database database = session.getDatabase();
151 synchronized (database) {
152 Session sysSession = database.getSystemSession();
153 if (!database.isSysTableLocked()) {
154 // this session may not lock the sys table (except if it already has locked it)
155 // because it must be committed immediately
156 // otherwise other threads can not access the sys table.
157 // if the table is not removed now, it will be when the database
158 // is opened the next time
159 // (the table is truncated, so this is just one record)
160 synchronized (sysSession) {
161 index.removeChildrenAndResources(sysSession);
162 table.removeChildrenAndResources(sysSession);
163 // the transaction must be committed immediately
164 sysSession.commit(false);
165 }
166 }
167 }
168 } finally {
169 table = null;
170 }
171 }
172
173 public void done() {
174 // nothing to do
175 }
176
177 public Value[] next() {
178 if (!resultCursor.next()) {
179 return null;
180 }
181 Row row = resultCursor.get();
182 ValueArray data = (ValueArray) row.getValue(0);
183 return data.getList();
184 }
185
186 public void reset() {
187 resultCursor = index.find(session, null, null);
188 }
189
190 private static Row convertToRow(Value[] values) {
191 ValueArray data = ValueArray.get(values);
192 return new Row(new Value[]{data}, Row.MEMORY_CALCULATE);
193 }
194
195 private Cursor find(Row row) {
196 Cursor cursor = index.find(session, row, row);
197 Value a = row.getValue(0);
198 while (cursor.next()) {
199 SearchRow found;
200 found = cursor.getSearchRow();
201 Value b = found.getValue(0);
202 if (session.getDatabase().areEqual(a, b)) {
203 return cursor;
204 }
205 }
206 return null;
207 }
208
209 }
210
211