Statistics
| Revision:

root / trunk / libraries / libGDBMS / src / main / java / com / hardcode / gdbms / engine / strategies / PDataSource.java @ 10627

History | View | Annotate | Download (5.59 KB)

1
package com.hardcode.gdbms.engine.strategies;
2

    
3
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
4
import com.hardcode.gdbms.engine.data.DataSource;
5
import com.hardcode.gdbms.engine.data.FieldNameAccessSupport;
6
import com.hardcode.gdbms.engine.data.persistence.Memento;
7
import com.hardcode.gdbms.engine.data.persistence.MementoException;
8
import com.hardcode.gdbms.engine.data.persistence.OperationLayerMemento;
9
import com.hardcode.gdbms.engine.values.Value;
10

    
11

    
12
/**
13
 * Clase que representa el producto cartesiano de dos o m?s tablas. El
14
 * almacenamiento de dicha tabla se realiza en las propias tablas sobre las
15
 * que se opera, haciendo los c?lculos en cada acceso para saber en qu? tabla
16
 * y en qu? posici?n de la tabla se encuentra el dato buscado
17
 *
18
 * @author Fernando Gonz?lez Cort?s
19
 */
20
public class PDataSource extends OperationDataSource {
21
        private DataSource[] tables;
22
        private long tablesArity;
23
        private FieldNameAccessSupport fnaSupport = new FieldNameAccessSupport(this);
24

    
25
        /**
26
         * Creates a new PDataSource object.
27
         *
28
         * @param tables Array de tablas que forman el producto
29
         */
30
        public PDataSource(DataSource[] tables) {
31
                this.tables = tables;
32
        }
33

    
34
        /**
35
         * Dado un ?ndice de campo en la tabla producto, devuelve el ?ndice en la
36
         * tabla operando a la cual pertenence el campo
37
         *
38
         * @param fieldId ?ndice en la tabla producto
39
         *
40
         * @return ?ndice en la tabla operando
41
         * @throws ReadDriverException TODO
42
         */
43
        private int getFieldIndex(int fieldId) throws ReadDriverException {
44
                int table = 0;
45

    
46
                while (fieldId >= tables[table].getFieldCount()) {
47
                        fieldId -= tables[table].getFieldCount();
48
                        table++;
49
                }
50

    
51
                return fieldId;
52
        }
53

    
54
        /**
55
         * Dado un ?ndice de campo en la tabla producto, devuelve el ?ndice en el
56
         * array de tablas de la tabla operando que contiene dicho campo
57
         *
58
         * @param fieldId ?ndice del campo en la tabla producto
59
         *
60
         * @return ?ndice de la tabla en el array de tablas
61
         * @throws ReadDriverException TODO
62
         */
63
        private int getTableIndexByFieldId(int fieldId) throws ReadDriverException {
64
                int table = 0;
65

    
66
                while (fieldId >= tables[table].getFieldCount()) {
67
                        fieldId -= tables[table].getFieldCount();
68
                        table++;
69
                }
70

    
71
                return table;
72
        }
73

    
74
        /**
75
         * Devuelve la fila de la tabla operando con ?ndice tableIndex que contiene
76
         * la informaci?n de la fila rowIndex en la tabla producto
77
         *
78
         * @param rowIndex fila en la tabla producto a la que se quiere acceder
79
         * @param tableIndex ?ndice de la tabla
80
         *
81
         * @return fila en la tabla operando de ?ndice tableIndex que se quiere
82
         *                    acceder
83
         * @throws ReadDriverException TODO
84
         * @throws ArrayIndexOutOfBoundsException Si la fila que se pide (rowIndex)
85
         *                    supera el n?mero de filas de la tabla producto
86
         */
87
        private long getTableRowIndexByTablePosition(long rowIndex, int tableIndex)
88
                throws ReadDriverException {
89
                if (rowIndex >= tablesArity) {
90
                        throw new ArrayIndexOutOfBoundsException();
91
                }
92

    
93
                int arity = 1;
94

    
95
                for (int i = tableIndex + 1; i < tables.length; i++) {
96
                        arity *= tables[i].getRowCount();
97
                }
98

    
99
                long selfArity = tables[tableIndex].getRowCount();
100

    
101
                return (rowIndex / arity) % selfArity;
102
        }
103

    
104
        /**
105
         * @see com.hardcode.gdbms.data.DataSource#getFieldName(int)
106
         */
107
        public String getFieldName(int fieldId) throws ReadDriverException {
108
                return tables[getTableIndexByFieldId(fieldId)].getFieldName(getFieldIndex(
109
                                fieldId));
110
        }
111

    
112
        /**
113
         * @see com.hardcode.gdbms.data.DataSource#getIntFieldValue(int, int)
114
         */
115
        public Value getFieldValue(long rowIndex, int fieldId)
116
                throws ReadDriverException {
117
                int tableIndex = getTableIndexByFieldId(fieldId);
118

    
119
                return tables[tableIndex].getFieldValue(getTableRowIndexByTablePosition(
120
                                rowIndex, tableIndex), getFieldIndex(fieldId));
121
        }
122

    
123
        /**
124
         * @see com.hardcode.gdbms.data.DataSource#getFieldCount()
125
         */
126
        public int getFieldCount() throws ReadDriverException {
127
                int ret = 0;
128

    
129
                for (int i = 0; i < tables.length; i++) {
130
                        ret += tables[i].getFieldCount();
131
                }
132

    
133
                return ret;
134
        }
135

    
136
        /**
137
         * @see com.hardcode.gdbms.data.DataSource#getRowCount()
138
         */
139
        public long getRowCount() throws ReadDriverException {
140
                return tablesArity;
141
        }
142

    
143
        /**
144
         * @see com.hardcode.gdbms.data.DataSource#open(java.io.File)
145
         */
146
        public void start() throws ReadDriverException {
147
                for (int i = 0; i < tables.length; i++) {
148
                        try {
149
                                tables[i].start();
150
                        } catch (ReadDriverException e) {
151
                                for (int j = 0; j < i; j++) {
152
                                        tables[i].stop();
153
                                }
154

    
155
                                throw e;
156
                        }
157
                }
158

    
159
                tablesArity = 1;
160

    
161
                for (int i = 0; i < tables.length; i++) {
162
                        tablesArity *= tables[i].getRowCount();
163
                }
164
        }
165

    
166
        /**
167
         * @see com.hardcode.gdbms.data.DataSource#close()
168
         */
169
        public void stop() throws ReadDriverException {
170
                for (int i = 0; i < tables.length; i++) {
171
                        tables[i].stop();
172
                }
173
        }
174

    
175
        /**
176
         * @see com.hardcode.gdbms.data.DataSource#getFieldIndexByName(String)
177
         */
178
        public int getFieldIndexByName(String fieldName) throws ReadDriverException {
179
                return fnaSupport.getFieldIndexByName(fieldName);
180
        }
181

    
182
        /**
183
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getFieldType(int)
184
         */
185
        public int getFieldType(int i) throws ReadDriverException {
186
                int table = getTableIndexByFieldId(i);
187

    
188
                return tables[table].getFieldType(getFieldIndex(i));
189
        }
190

    
191
        /**
192
         * @see com.hardcode.gdbms.engine.data.DataSource#getMemento()
193
         */
194
        public Memento getMemento() throws MementoException {
195
                Memento[] mementos = new Memento[tables.length];
196

    
197
                for (int i = 0; i < mementos.length; i++) {
198
                        mementos[i] = tables[i].getMemento();
199
                }
200

    
201
                return new OperationLayerMemento(getName(), mementos, getSQL());
202
        }
203

    
204
        public int getFieldWidth(int i) throws ReadDriverException {
205
                int table = getTableIndexByFieldId(i);
206

    
207
                return tables[table].getFieldWidth(getFieldIndex(i));
208
        }
209
}