Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.jdbc / src / main / java / org / gvsig / fmap / dal / store / jdbc2 / impl / ResulSetControlerBase.java @ 43020

History | View | Annotate | Download (6.41 KB)

1
package org.gvsig.fmap.dal.store.jdbc2.impl;
2

    
3
import java.sql.Connection;
4
import java.sql.PreparedStatement;
5
import java.sql.ResultSet;
6
import java.sql.SQLException;
7
import java.sql.Statement;
8
import java.util.ArrayList;
9
import java.util.HashMap;
10
import java.util.List;
11
import java.util.Map;
12
import org.gvsig.fmap.dal.exception.DataException;
13
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecutePreparedSQLException;
14
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
15
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
16
import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler;
17
import org.slf4j.Logger;
18
import org.slf4j.LoggerFactory;
19

    
20
public class ResulSetControlerBase implements ResulSetControler {
21

    
22
    final static private Logger logger = LoggerFactory.getLogger(ResulSetControlerBase.class);
23

    
24
    public class ResultSetEntryBase implements ResultSetEntry {
25

    
26
        private ResultSet resultSet = null;
27
        private final int id;
28
        private long lastUse = 0;
29
        private String sql;
30

    
31
        public ResultSetEntryBase(ResultSet resulSet) {
32
            this(resulSet,null);
33
        }
34

    
35
        public ResultSetEntryBase(ResultSet resulSet, String sql) {
36
            this.resultSet = resulSet;
37
            this.id = nextid++;
38
            this.sql = sql;
39
            used();
40
            resulSets.put(this.getID(), this);
41
        }
42

    
43
        private void used() {
44
            lastUse = System.currentTimeMillis();
45
        }
46

    
47
        @Override
48
        public ResultSet get() {
49
            used();
50
            return resultSet;
51
        }
52

    
53
        @Override
54
        public int getID() {
55
            return this.id;
56
        }
57

    
58
        @Override
59
        public boolean isZombie() {
60
            if( this.resultSet == null ) {
61
                return true;
62
            }
63
            return System.currentTimeMillis() - lastUse > mlsecondsToZombie;
64
        }
65

    
66
        @Override
67
        public String getSQL() {
68
            return this.sql;
69
        }
70

    
71
        @Override
72
        public Object getObject(int columnIndex) throws SQLException {
73
            used();
74
            return this.resultSet.getObject(columnIndex);
75
        }
76

    
77
        @Override
78
        public byte[] getBytes(int columnIndex) throws SQLException {
79
            used();
80
            return this.resultSet.getBytes(columnIndex);
81
        }
82

    
83
        @Override
84
        public boolean next() throws SQLException {
85
            return this.resultSet.next();
86
        }
87

    
88
        @Override
89
        public void close() throws Exception {
90
            if( this.resultSet == null ) {
91
                // Already close
92
                return;
93
            }
94
            Statement st = null;
95
            Connection con = null;
96
            try {
97
                resulSets.remove(this.getID());
98
                st = this.resultSet.getStatement();
99
                if( st != null ) {
100
                    con = st.getConnection();
101
                }
102
            } catch(Exception ex) {
103
                logger.warn("Problems closing ResulSetEntryBase.",ex);
104
            }
105
            JDBCUtils.closeQuietly(this.resultSet);
106
            JDBCUtils.closeQuietly(st);
107
            JDBCUtils.closeQuietly(con);
108
            this.resultSet = null;
109
            logger.debug(
110
                    "Close ResulSetEntryBase id {} (total {})",
111
                    this.getID(),
112
                    getOpenCount()
113
            );
114
            pack();
115
        }
116

    
117
    }
118

    
119
    private int nextid = 1;
120

    
121
    private Map<Integer, ResultSetEntryBase> resulSets;
122

    
123
    private long mlsecondsToZombie = 1000 * 60 * 10; // 10 Min
124

    
125
    private JDBCHelper helper = null;
126

    
127
    public ResulSetControlerBase(JDBCHelper helper) {
128
        this.helper = helper;
129
        this.resulSets = new HashMap<>();
130
        this.nextid = 1;
131
    }
132

    
133
    @Override
134
    public long getTimeToZombie() {
135
        return mlsecondsToZombie;
136
    }
137

    
138
    @Override
139
    public void setTimeToZombie(long mlSeconds) {
140
        mlsecondsToZombie = mlSeconds;
141
    }
142

    
143
    @Override
144
    public void close() throws Exception {
145
        this.closeAll();
146
        this.helper = null;
147
        this.resulSets = null;
148
        this.nextid = -10;
149
    }
150

    
151
    @Override
152
    public ResultSetEntryBase create(String sql, int fetchSize) throws DataException {
153
        return create(sql, null, fetchSize);
154
    }
155

    
156
    @Override
157
    public synchronized ResultSetEntryBase create(
158
            final String sql,
159
            final List values,
160
            final int fetchSize) throws DataException {
161

    
162
        this.pack();
163
        ResultSet rs = null;
164
        Connection conn = null;
165
        PreparedStatement st = null;
166
        try {
167
            conn = helper.getConnection();
168
            conn.setAutoCommit(false);
169
            st = conn.prepareStatement(sql);
170

    
171
            JDBCUtils.setObjects(st, values, helper.getGeometrySupportType());
172

    
173
            if (fetchSize > 0) {
174
                st.setFetchSize(fetchSize);
175
            }
176
            rs = JDBCUtils.executeQuery(st, sql);
177
            if (fetchSize > 0) {
178
                rs.setFetchSize(fetchSize);
179
            }
180

    
181
        } catch (SQLException e) {
182
            JDBCUtils.closeQuietly(rs);
183
            JDBCUtils.closeQuietly(st);
184
            JDBCUtils.closeQuietly(conn);
185
            throw new JDBCExecutePreparedSQLException(sql, values, e);
186
        }
187
        ResultSetEntryBase rsentry = new ResultSetEntryBase(rs, sql);
188
        return rsentry;
189
    }
190

    
191
    @Override
192
    public synchronized void closeAll() {
193

    
194
        // Para evitar problemas de concurrencia al eliminar elementos del
195
        // map mientras lo recorremos, cargamos las entredas en un List
196
        List<ResultSetEntryBase> entries = new ArrayList<>();
197
        entries.addAll(this.resulSets.values());
198

    
199
        for (ResultSetEntryBase entry : entries) {
200
            JDBCUtils.closeQuietly(entry);
201
        }
202
    }
203

    
204
    @Override
205
    public synchronized void pack() {
206
        // Para evitar problemas de concurrencia al eliminar elementos del
207
        // map mientras lo recorremos, cargamos las entredas en un List
208
        List<ResultSetEntryBase> entries = new ArrayList<>();
209
        entries.addAll(this.resulSets.values());
210

    
211
        int maxID = 0;
212
        for (ResultSetEntryBase entry : entries) {
213
            if (entry.isZombie()) {
214
                JDBCUtils.closeQuietly(entry);
215
            } else {
216
                if (entry.getID() > maxID) {
217
                    maxID = entry.getID();
218
                }
219
            }
220
        }
221
        this.nextid = maxID + 1;
222
    }
223

    
224
    @Override
225
    public synchronized int getOpenCount() {
226
        return this.resulSets.size();
227
    }
228
}