Repository navigation
Expand file tree
/
Copy pathSQLPool.java
More file actions
103 lines (86 loc) · 3 KB
/
Copy pathSQLPool.java
File metadata and controls
103 lines (86 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package org.javawebstack.orm.connection.pool;
import org.javawebstack.orm.connection.QueryLogger;
import org.javawebstack.orm.connection.SQL;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Supplier;
public class SQLPool {
private final PoolScaling scaling;
private final Supplier<SQL> supplier;
private final List<SQL> connections = new ArrayList<>();
private final BlockingQueue<SQL> connectionQueue = new LinkedBlockingQueue<>();
private final Set<QueryLogger> loggers = new HashSet<>();
private boolean closing;
private PoolQueryLogger queryLogger = new PoolQueryLogger();
public SQLPool(PoolScaling scaling, Supplier<SQL> supplier) {
this.scaling = scaling;
this.supplier = supplier;
this.scale();
}
public SQLPool(int min, int max, Supplier<SQL> supplier) {
this(new MinMaxScaler(min, max), supplier);
}
public PooledSQL get() {
if(closing)
throw new IllegalStateException("Pool has already been closed");
scale();
try {
SQL sql = connectionQueue.take();
scale();
return new PooledSQL(this, sql);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void release(SQL sql) {
if(!closing) {
if(sql instanceof PooledSQL) {
sql.close();
return;
}
if(!connections.contains(sql))
throw new IllegalArgumentException("Not a connection of this pool");
connectionQueue.add(sql);
scale();
}
}
public void addQueryLogger(QueryLogger logger) {
loggers.add(logger);
}
public void removeQueryLogger(QueryLogger logger) {
loggers.remove(logger);
}
public void scale() {
if(closing)
throw new IllegalStateException("Pool has already been closed");
int newScale = scaling.scale(connections.size(), connections.size() - connectionQueue.size());
if(newScale == connections.size())
return;
synchronized(this) {
while (newScale > connections.size()) {
SQL sql = supplier.get();
sql.addQueryLogger(queryLogger);
connections.add(sql);
connectionQueue.add(sql);
}
while (newScale < connections.size() && connectionQueue.size() > 0) {
SQL sql = connectionQueue.poll();
sql.close();
connections.remove(sql);
}
}
}
public void close() {
closing = true;
for(SQL connection : connections) {
connection.close();
}
}
private class PoolQueryLogger implements QueryLogger {
public void log(String query, Object[] parameters) {
for(QueryLogger logger : loggers)
logger.log(query, parameters);
}
}
}