Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libGDBMS / src / main / java / com / hardcode / gdbms / engine / strategies / PDataSource.java @ 4851

History | View | Annotate | Download (5.69 KB)

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

    
3
import com.hardcode.gdbms.engine.data.DataSource;
4
import com.hardcode.gdbms.engine.data.FieldNameAccessSupport;
5
import com.hardcode.gdbms.engine.data.driver.DriverException;
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
         *
42
         * @throws DriverException Si se prouce alg?n error accediendo a la tabla
43
         *                    operando
44
         */
45
        private int getFieldIndex(int fieldId) throws DriverException {
46
                int table = 0;
47

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

    
53
                return fieldId;
54
        }
55

    
56
        /**
57
         * Dado un ?ndice de campo en la tabla producto, devuelve el ?ndice en el
58
         * array de tablas de la tabla operando que contiene dicho campo
59
         *
60
         * @param fieldId ?ndice del campo en la tabla producto
61
         *
62
         * @return ?ndice de la tabla en el array de tablas
63
         *
64
         * @throws DriverException Si se prouce alg?n error accediendo a la tabla
65
         *                    operando
66
         */
67
        private int getTableIndexByFieldId(int fieldId) throws DriverException {
68
                int table = 0;
69

    
70
                while (fieldId >= tables[table].getFieldCount()) {
71
                        fieldId -= tables[table].getFieldCount();
72
                        table++;
73
                }
74

    
75
                return table;
76
        }
77

    
78
        /**
79
         * Devuelve la fila de la tabla operando con ?ndice tableIndex que contiene
80
         * la informaci?n de la fila rowIndex en la tabla producto
81
         *
82
         * @param rowIndex fila en la tabla producto a la que se quiere acceder
83
         * @param tableIndex ?ndice de la tabla
84
         *
85
         * @return fila en la tabla operando de ?ndice tableIndex que se quiere
86
         *                    acceder
87
         *
88
         * @throws DriverException Si se prouce alg?n error accediendo a la tabla
89
         *                    operando
90
         * @throws ArrayIndexOutOfBoundsException Si la fila que se pide (rowIndex)
91
         *                    supera el n?mero de filas de la tabla producto
92
         */
93
        private long getTableRowIndexByTablePosition(long rowIndex, int tableIndex)
94
                throws DriverException {
95
                if (rowIndex >= tablesArity) {
96
                        throw new ArrayIndexOutOfBoundsException();
97
                }
98

    
99
                int arity = 1;
100

    
101
                for (int i = tableIndex + 1; i < tables.length; i++) {
102
                        arity *= tables[i].getRowCount();
103
                }
104

    
105
                long selfArity = tables[tableIndex].getRowCount();
106

    
107
                return (rowIndex / arity) % selfArity;
108
        }
109

    
110
        /**
111
         * @see com.hardcode.gdbms.data.DataSource#getFieldName(int)
112
         */
113
        public String getFieldName(int fieldId) throws DriverException {
114
                return tables[getTableIndexByFieldId(fieldId)].getFieldName(getFieldIndex(
115
                                fieldId));
116
        }
117

    
118
        /**
119
         * @see com.hardcode.gdbms.data.DataSource#getIntFieldValue(int, int)
120
         */
121
        public Value getFieldValue(long rowIndex, int fieldId)
122
                throws DriverException {
123
                int tableIndex = getTableIndexByFieldId(fieldId);
124

    
125
                return tables[tableIndex].getFieldValue(getTableRowIndexByTablePosition(
126
                                rowIndex, tableIndex), getFieldIndex(fieldId));
127
        }
128

    
129
        /**
130
         * @see com.hardcode.gdbms.data.DataSource#getFieldCount()
131
         */
132
        public int getFieldCount() throws DriverException {
133
                int ret = 0;
134

    
135
                for (int i = 0; i < tables.length; i++) {
136
                        ret += tables[i].getFieldCount();
137
                }
138

    
139
                return ret;
140
        }
141

    
142
        /**
143
         * @see com.hardcode.gdbms.data.DataSource#getRowCount()
144
         */
145
        public long getRowCount() {
146
                return tablesArity;
147
        }
148

    
149
        /**
150
         * @see com.hardcode.gdbms.data.DataSource#open(java.io.File)
151
         */
152
        public void start() throws DriverException {
153
                for (int i = 0; i < tables.length; i++) {
154
                        try {
155
                                tables[i].start();
156
                        } catch (DriverException e) {
157
                                for (int j = 0; j < i; j++) {
158
                                        tables[i].stop();
159
                                }
160

    
161
                                throw e;
162
                        }
163
                }
164

    
165
                tablesArity = 1;
166

    
167
                for (int i = 0; i < tables.length; i++) {
168
                        tablesArity *= tables[i].getRowCount();
169
                }
170
        }
171

    
172
        /**
173
         * @see com.hardcode.gdbms.data.DataSource#close()
174
         */
175
        public void stop() throws DriverException {
176
                for (int i = 0; i < tables.length; i++) {
177
                        tables[i].stop();
178
                }
179
        }
180

    
181
        /**
182
         * @see com.hardcode.gdbms.data.DataSource#getFieldIndexByName(String)
183
         */
184
        public int getFieldIndexByName(String fieldName) throws DriverException {
185
                return fnaSupport.getFieldIndexByName(fieldName);
186
        }
187

    
188
        /**
189
         * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getFieldType(int)
190
         */
191
        public int getFieldType(int i) throws DriverException {
192
                int table = getTableIndexByFieldId(i);
193

    
194
                return tables[table].getFieldType(getFieldIndex(i));
195
        }
196

    
197
        /**
198
         * @see com.hardcode.gdbms.engine.data.DataSource#getMemento()
199
         */
200
        public Memento getMemento() throws MementoException {
201
                Memento[] mementos = new Memento[tables.length];
202

    
203
                for (int i = 0; i < mementos.length; i++) {
204
                        mementos[i] = tables[i].getMemento();
205
                }
206

    
207
                return new OperationLayerMemento(getName(), mementos, getSQL());
208
        }
209

    
210
        public int getFieldWidth(int i) throws DriverException {
211
                int table = getTableIndexByFieldId(i);
212

    
213
                return tables[table].getFieldWidth(getFieldIndex(i));
214
        }
215
}