OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 17 | Rev 65 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.sql.model;
15
 
16
import org.openconcerto.utils.Tuple2;
17
 
18
import java.sql.ResultSet;
19
import java.sql.SQLException;
20
import java.util.ArrayList;
21
import java.util.List;
22
 
23
import org.apache.commons.dbutils.ResultSetHandler;
24
 
25
public final class SQLRowListRSH implements ResultSetHandler {
26
 
63 ilm 27
    // hashCode()/equals() needed for data source cache
28
    private static final class RSH implements ResultSetHandler {
29
        private final Tuple2<SQLTable, List<String>> names;
30
 
31
        private RSH(Tuple2<SQLTable, List<String>> names) {
32
            this.names = names;
33
        }
34
 
35
        @Override
36
        public List<SQLRow> handle(ResultSet rs) throws SQLException {
37
            return SQLRow.createListFromRS(this.names.get0(), rs, this.names.get1());
38
        }
39
 
40
        @Override
41
        public int hashCode() {
42
            return this.names.hashCode();
43
        }
44
 
45
        @Override
46
        public boolean equals(Object obj) {
47
            if (this == obj)
48
                return true;
49
            if (obj == null)
50
                return false;
51
            if (getClass() != obj.getClass())
52
                return false;
53
            final RSH other = (RSH) obj;
54
            return this.names.equals(other.names);
55
        }
56
    }
57
 
17 ilm 58
    private static Tuple2<SQLTable, List<String>> getIndexes(SQLSelect sel, final SQLTable passedTable, final boolean findTable) {
59
        final List<SQLField> selectFields = sel.getSelectFields();
60
        final int size = selectFields.size();
61
        if (size == 0)
62
            throw new IllegalArgumentException("empty select : " + sel);
63
        final SQLTable t;
64
        if (findTable) {
65
            if (passedTable != null)
66
                throw new IllegalArgumentException("non null table " + passedTable);
67
            t = selectFields.get(0).getTable();
68
        } else {
69
            if (passedTable == null)
70
                throw new IllegalArgumentException("null table");
71
            t = passedTable;
72
        }
73
        // cannot pass an alias to this method since getSelectFields() returns SQLField and not
74
        // FieldRef
75
        final List<AliasedTable> aliases = sel.getAliases(t);
76
        if (aliases.size() != 1)
77
            throw new IllegalArgumentException(t + " isn't exactly once : " + aliases);
78
        final List<String> l = new ArrayList<String>(size);
79
        for (int i = 0; i < size; i++) {
80
            final SQLField field = selectFields.get(i);
81
            if (field.getTable().equals(t))
82
                l.add(field.getName());
83
            else if (findTable)
84
                throw new IllegalArgumentException(field + " is not in " + t);
85
            else
86
                l.add(null);
87
        }
88
        return Tuple2.create(t, l);
89
    }
90
 
91
    /**
92
     * Create a handler that don't need metadata.
93
     *
94
     * @param sel the select that will produce the result set, must only have one table.
95
     * @return a handler creating a list of {@link SQLRow}.
96
     */
97
    static public ResultSetHandler createFromSelect(final SQLSelect sel) {
98
        return create(getIndexes(sel, null, true));
99
    }
100
 
101
    /**
102
     * Create a handler that don't need metadata. Useful since some JDBC drivers perform queries for
103
     * each metadata.
104
     *
105
     * @param sel the select that will produce the result set.
106
     * @param t the table for which to create rows, must appear only once in <code>sel</code>.
107
     * @return a handler creating a list of {@link SQLRow}.
108
     */
109
    static public ResultSetHandler createFromSelect(final SQLSelect sel, final SQLTable t) {
110
        return create(getIndexes(sel, t, false));
111
    }
112
 
113
    static private ResultSetHandler create(final Tuple2<SQLTable, List<String>> names) {
63 ilm 114
        return new RSH(names);
17 ilm 115
    }
116
 
117
    @SuppressWarnings("unchecked")
118
    static public List<SQLRow> execute(final SQLSelect sel) {
119
        final Tuple2<SQLTable, List<String>> indexes = getIndexes(sel, null, true);
120
        return (List<SQLRow>) indexes.get0().getDBSystemRoot().getDataSource().execute(sel.asString(), create(indexes));
121
    }
122
 
123
    private final SQLTable t;
124
    private final boolean tableOnly;
125
 
126
    public SQLRowListRSH(SQLTable t) {
127
        this(t, false);
128
    }
129
 
130
    public SQLRowListRSH(SQLTable t, final boolean tableOnly) {
131
        super();
132
        this.t = t;
133
        this.tableOnly = tableOnly;
134
    }
135
 
136
    public Object handle(ResultSet rs) throws SQLException {
137
        return SQLRow.createListFromRS(this.t, rs, this.tableOnly);
138
    }
139
}