root / trunk / libraries / libGDBMS / src / main / java / com / hardcode / gdbms / engine / strategies / DistinctDataSource.java @ 10627
History | View | Annotate | Download (5.68 KB)
1 |
package com.hardcode.gdbms.engine.strategies; |
---|---|
2 |
|
3 |
import java.util.Comparator; |
4 |
import java.util.TreeSet; |
5 |
|
6 |
import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
7 |
import com.hardcode.gdbms.engine.data.DataSource; |
8 |
import com.hardcode.gdbms.engine.data.FieldNameAccessSupport; |
9 |
import com.hardcode.gdbms.engine.data.persistence.Memento; |
10 |
import com.hardcode.gdbms.engine.data.persistence.MementoException; |
11 |
import com.hardcode.gdbms.engine.data.persistence.OperationLayerMemento; |
12 |
import com.hardcode.gdbms.engine.instruction.EvaluationException; |
13 |
import com.hardcode.gdbms.engine.instruction.Expression; |
14 |
import com.hardcode.gdbms.engine.instruction.IncompatibleTypesException; |
15 |
import com.hardcode.gdbms.engine.internalExceptions.InternalException; |
16 |
import com.hardcode.gdbms.engine.internalExceptions.InternalExceptionCatcher; |
17 |
import com.hardcode.gdbms.engine.internalExceptions.InternalExceptionEvent; |
18 |
import com.hardcode.gdbms.engine.values.BooleanValue; |
19 |
import com.hardcode.gdbms.engine.values.Value; |
20 |
import com.hardcode.gdbms.engine.values.ValueCollection; |
21 |
import com.hardcode.gdbms.engine.values.ValueFactory; |
22 |
|
23 |
|
24 |
/**
|
25 |
* DOCUMENT ME!
|
26 |
*
|
27 |
* @author Fernando Gonz?lez Cort?s
|
28 |
*/
|
29 |
public class DistinctDataSource extends OperationDataSource { |
30 |
private DataSource dataSource; |
31 |
private int[] indexes; |
32 |
private FieldNameAccessSupport fnaSupport = new FieldNameAccessSupport(this); |
33 |
private Expression[] expressions; |
34 |
|
35 |
/**
|
36 |
* Crea un nuevo DistinctDataSource.
|
37 |
*
|
38 |
* @param ds DOCUMENT ME!
|
39 |
* @param expressions DOCUMENT ME!
|
40 |
*/
|
41 |
public DistinctDataSource(DataSource ds, Expression[] expressions) { |
42 |
dataSource = ds; |
43 |
this.expressions = expressions;
|
44 |
} |
45 |
|
46 |
/**
|
47 |
* @see com.hardcode.gdbms.engine.data.DataSource#start()
|
48 |
*/
|
49 |
public void start() throws ReadDriverException { |
50 |
dataSource.start(); |
51 |
} |
52 |
|
53 |
/**
|
54 |
* @see com.hardcode.gdbms.engine.data.DataSource#stop()
|
55 |
*/
|
56 |
public void stop() throws ReadDriverException { |
57 |
dataSource.stop(); |
58 |
} |
59 |
|
60 |
/**
|
61 |
* @see com.hardcode.gdbms.engine.data.DataSource#getMemento()
|
62 |
*/
|
63 |
public Memento getMemento() throws MementoException { |
64 |
return new OperationLayerMemento(getName(), |
65 |
new Memento[] { dataSource.getMemento() }, getSQL()); |
66 |
} |
67 |
|
68 |
/**
|
69 |
* @see com.hardcode.gdbms.engine.data.DataSource#getFieldIndexByName(java.lang.String)
|
70 |
*/
|
71 |
public int getFieldIndexByName(String fieldName) throws ReadDriverException { |
72 |
return fnaSupport.getFieldIndexByName(fieldName);
|
73 |
} |
74 |
|
75 |
/**
|
76 |
* @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldValue(long,
|
77 |
* int)
|
78 |
*/
|
79 |
public Value getFieldValue(long rowIndex, int fieldId) |
80 |
throws ReadDriverException {
|
81 |
return dataSource.getFieldValue(indexes[(int) rowIndex], fieldId); |
82 |
} |
83 |
|
84 |
/**
|
85 |
* @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldCount()
|
86 |
*/
|
87 |
public int getFieldCount() throws ReadDriverException { |
88 |
return dataSource.getFieldCount();
|
89 |
} |
90 |
|
91 |
/**
|
92 |
* @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldName(int)
|
93 |
*/
|
94 |
public String getFieldName(int fieldId) throws ReadDriverException { |
95 |
return dataSource.getFieldName(fieldId);
|
96 |
} |
97 |
|
98 |
/**
|
99 |
* @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getRowCount()
|
100 |
*/
|
101 |
public long getRowCount() throws ReadDriverException { |
102 |
return indexes.length;
|
103 |
} |
104 |
|
105 |
/**
|
106 |
* @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldType(int)
|
107 |
*/
|
108 |
public int getFieldType(int i) throws ReadDriverException { |
109 |
return dataSource.getFieldType(i);
|
110 |
} |
111 |
|
112 |
/**
|
113 |
* DOCUMENT ME!
|
114 |
* @throws EvaluationException DOCUMENT ME!
|
115 |
* @throws ReadDriverException TODO
|
116 |
* @throws RuntimeException DOCUMENT ME!
|
117 |
*/
|
118 |
public void filter() throws EvaluationException, ReadDriverException { |
119 |
int[] idx = new int[(int) dataSource.getRowCount()]; |
120 |
TreeSet h = new TreeSet(new Comparator() { |
121 |
public int compare(Object o1, Object o2) { |
122 |
try {
|
123 |
Value v1 = (Value) o1; |
124 |
Value v2 = (Value) o2; |
125 |
|
126 |
if (((BooleanValue) v1.equals(v2)).getValue()) {
|
127 |
return 0; |
128 |
} else {
|
129 |
return 1; |
130 |
} |
131 |
} catch (IncompatibleTypesException e) {
|
132 |
InternalExceptionCatcher.callExceptionRaised(new InternalExceptionEvent(DistinctDataSource.this, new InternalException("Internal error calculating distinct clause", e))); |
133 |
return 0; |
134 |
} |
135 |
} |
136 |
}); |
137 |
int index = 0; |
138 |
|
139 |
for (int i = 0; i < dataSource.getRowCount(); i++) { |
140 |
Value[] values;
|
141 |
if (expressions == null){ |
142 |
values = new Value[dataSource.getFieldCount()];
|
143 |
for (int j = 0; j < values.length; j++) { |
144 |
values[j] = dataSource.getFieldValue(i, j); |
145 |
} |
146 |
} else {
|
147 |
values = new Value[expressions.length];
|
148 |
for (int j = 0; j < values.length; j++) { |
149 |
values[j] = expressions[j].evaluate(i); |
150 |
} |
151 |
} |
152 |
|
153 |
ValueCollection vc = ValueFactory.createValue(values); |
154 |
|
155 |
if (!h.contains(vc)) {
|
156 |
idx[index] = i; |
157 |
index++; |
158 |
h.add(vc); |
159 |
} |
160 |
} |
161 |
|
162 |
indexes = new int[index]; |
163 |
System.arraycopy(idx, 0, indexes, 0, index); |
164 |
} |
165 |
|
166 |
public int getFieldWidth(int i) throws ReadDriverException { |
167 |
return dataSource.getFieldType(i);
|
168 |
} |
169 |
} |