Skip to content

Commit 1a5eb49

Browse files
authored
Merge pull request #23 from shy1st/master
Optimize to load policy by reducing the number of database connections.
2 parents 2a21149 + 1e9f3a4 commit 1a5eb49

File tree

3 files changed

+93
-64
lines changed

3 files changed

+93
-64
lines changed

src/main/java/org/casbin/adapter/JDBCAdapter.java

+67-62
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.casbin.jcasbin.persist.Helper;
2222

2323
import javax.sql.DataSource;
24-
import java.math.BigDecimal;
2524
import java.sql.*;
2625
import java.util.*;
2726

@@ -41,8 +40,9 @@ class CasbinRule {
4140
* It can load policy from JDBC supported database or save policy to it.
4241
*/
4342
public class JDBCAdapter implements Adapter {
44-
private DataSource dataSource = null;
43+
private DataSource dataSource;
4544
private final int batchSize = 1000;
45+
private Connection conn;
4646

4747
/**
4848
* JDBCAdapter is the constructor for JDBCAdapter.
@@ -67,62 +67,62 @@ public JDBCAdapter(DataSource dataSource) throws Exception {
6767
}
6868

6969
private void migrate() throws SQLException {
70-
try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
71-
String sql = "CREATE TABLE IF NOT EXISTS casbin_rule(id int NOT NULL PRIMARY KEY auto_increment, ptype VARCHAR(100) NOT NULL, v0 VARCHAR(100), v1 VARCHAR(100), v2 VARCHAR(100), v3 VARCHAR(100), v4 VARCHAR(100), v5 VARCHAR(100))";
72-
String productName = conn.getMetaData().getDatabaseProductName();
73-
74-
switch (productName) {
75-
case "Oracle":
76-
sql = "declare begin execute immediate 'CREATE TABLE CASBIN_RULE(id NUMBER(5, 0) not NULL primary key, ptype VARCHAR(100) not NULL, v0 VARCHAR(100), v1 VARCHAR(100), v2 VARCHAR(100), v3 VARCHAR(100), v4 VARCHAR(100), v5 VARCHAR(100))'; " +
77-
"exception when others then " +
78-
"if SQLCODE = -955 then " +
79-
"null; " +
80-
"else raise; " +
81-
"end if; " +
82-
"end;";
83-
break;
84-
case "Microsoft SQL Server":
85-
sql = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='casbin_rule' and xtype='U') CREATE TABLE casbin_rule(id int NOT NULL primary key identity(1, 1), ptype VARCHAR(100) NOT NULL, v0 VARCHAR(100), v1 VARCHAR(100), v2 VARCHAR(100), v3 VARCHAR(100), v4 VARCHAR(100), v5 VARCHAR(100))";
86-
break;
87-
case "PostgreSQL":
88-
sql = "CREATE SEQUENCE IF NOT EXISTS CASBIN_SEQUENCE START 1;";
89-
break;
90-
}
70+
conn = dataSource.getConnection();
71+
Statement stmt = conn.createStatement();
72+
String sql = "CREATE TABLE IF NOT EXISTS casbin_rule(id int NOT NULL PRIMARY KEY auto_increment, ptype VARCHAR(100) NOT NULL, v0 VARCHAR(100), v1 VARCHAR(100), v2 VARCHAR(100), v3 VARCHAR(100), v4 VARCHAR(100), v5 VARCHAR(100))";
73+
String productName = conn.getMetaData().getDatabaseProductName();
74+
75+
switch (productName) {
76+
case "Oracle":
77+
sql = "declare begin execute immediate 'CREATE TABLE CASBIN_RULE(id NUMBER(5, 0) not NULL primary key, ptype VARCHAR(100) not NULL, v0 VARCHAR(100), v1 VARCHAR(100), v2 VARCHAR(100), v3 VARCHAR(100), v4 VARCHAR(100), v5 VARCHAR(100))'; " +
78+
"exception when others then " +
79+
"if SQLCODE = -955 then " +
80+
"null; " +
81+
"else raise; " +
82+
"end if; " +
83+
"end;";
84+
break;
85+
case "Microsoft SQL Server":
86+
sql = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='casbin_rule' and xtype='U') CREATE TABLE casbin_rule(id int NOT NULL primary key identity(1, 1), ptype VARCHAR(100) NOT NULL, v0 VARCHAR(100), v1 VARCHAR(100), v2 VARCHAR(100), v3 VARCHAR(100), v4 VARCHAR(100), v5 VARCHAR(100))";
87+
break;
88+
case "PostgreSQL":
89+
sql = "CREATE SEQUENCE IF NOT EXISTS CASBIN_SEQUENCE START 1;";
90+
break;
91+
}
9192

93+
stmt.executeUpdate(sql);
94+
if (productName.equals("Oracle")) {
95+
sql = "declare " +
96+
"V_NUM number;" +
97+
"BEGIN " +
98+
"V_NUM := 0; " +
99+
"select count(0) into V_NUM from user_sequences where sequence_name = 'CASBIN_SEQUENCE';" +
100+
"if V_NUM > 0 then " +
101+
"null;" +
102+
"else " +
103+
"execute immediate 'CREATE SEQUENCE casbin_sequence increment by 1 start with 1 nomaxvalue nocycle nocache';" +
104+
"end if;END;";
105+
stmt.executeUpdate(sql);
106+
sql = "declare " +
107+
"V_NUM number;" +
108+
"BEGIN " +
109+
"V_NUM := 0;" +
110+
"select count(0) into V_NUM from user_triggers where trigger_name = 'CASBIN_ID_AUTOINCREMENT';" +
111+
"if V_NUM > 0 then " +
112+
"null;" +
113+
"else " +
114+
"execute immediate 'create trigger casbin_id_autoincrement before "+
115+
" insert on CASBIN_RULE for each row "+
116+
" when (new.id is null) "+
117+
" begin "+
118+
" select casbin_sequence.nextval into:new.id from dual;"+
119+
" end;';" +
120+
"end if;" +
121+
"END;";
122+
stmt.executeUpdate(sql);
123+
} else if (productName.equals("PostgreSQL")) {
124+
sql = "CREATE TABLE IF NOT EXISTS casbin_rule(id int NOT NULL PRIMARY KEY default nextval('CASBIN_SEQUENCE'::regclass), ptype VARCHAR(100) NOT NULL, v0 VARCHAR(100), v1 VARCHAR(100), v2 VARCHAR(100), v3 VARCHAR(100), v4 VARCHAR(100), v5 VARCHAR(100))";
92125
stmt.executeUpdate(sql);
93-
if (productName.equals("Oracle")) {
94-
sql = "declare " +
95-
"V_NUM number;" +
96-
"BEGIN " +
97-
"V_NUM := 0; " +
98-
"select count(0) into V_NUM from user_sequences where sequence_name = 'CASBIN_SEQUENCE';" +
99-
"if V_NUM > 0 then " +
100-
"null;" +
101-
"else " +
102-
"execute immediate 'CREATE SEQUENCE casbin_sequence increment by 1 start with 1 nomaxvalue nocycle nocache';" +
103-
"end if;END;";
104-
stmt.executeUpdate(sql);
105-
sql = "declare " +
106-
"V_NUM number;" +
107-
"BEGIN " +
108-
"V_NUM := 0;" +
109-
"select count(0) into V_NUM from user_triggers where trigger_name = 'CASBIN_ID_AUTOINCREMENT';" +
110-
"if V_NUM > 0 then " +
111-
"null;" +
112-
"else " +
113-
"execute immediate 'create trigger casbin_id_autoincrement before "+
114-
" insert on CASBIN_RULE for each row "+
115-
" when (new.id is null) "+
116-
" begin "+
117-
" select casbin_sequence.nextval into:new.id from dual;"+
118-
" end;';" +
119-
"end if;" +
120-
"END;";
121-
stmt.executeUpdate(sql);
122-
} else if (productName.equals("PostgreSQL")) {
123-
sql = "CREATE TABLE IF NOT EXISTS casbin_rule(id int NOT NULL PRIMARY KEY default nextval('CASBIN_SEQUENCE'::regclass), ptype VARCHAR(100) NOT NULL, v0 VARCHAR(100), v1 VARCHAR(100), v2 VARCHAR(100), v3 VARCHAR(100), v4 VARCHAR(100), v5 VARCHAR(100))";
124-
stmt.executeUpdate(sql);
125-
}
126126
}
127127
}
128128

@@ -155,8 +155,7 @@ private void loadPolicyLine(CasbinRule line, Model model) {
155155
*/
156156
@Override
157157
public void loadPolicy(Model model) {
158-
try (Connection conn = dataSource.getConnection()) {
159-
Statement stmt = conn.createStatement();
158+
try (Statement stmt = conn.createStatement()) {
160159
ResultSet rSet = stmt.executeQuery("SELECT * FROM casbin_rule");
161160
ResultSetMetaData rData = rSet.getMetaData();
162161
while (rSet.next()) {
@@ -221,7 +220,7 @@ public void savePolicy(Model model) {
221220
String cleanSql = "delete from casbin_rule";
222221
String addSql = "INSERT INTO casbin_rule (ptype,v0,v1,v2,v3,v4,v5) VALUES(?,?,?,?,?,?,?)";
223222

224-
try (Connection conn = dataSource.getConnection()) {
223+
try {
225224
conn.setAutoCommit(false);
226225

227226
int count = 0;
@@ -298,7 +297,7 @@ public void addPolicy(String sec, String ptype, List<String> rule) {
298297

299298
String sql = "INSERT INTO casbin_rule (ptype,v0,v1,v2,v3,v4,v5) VALUES(?,?,?,?,?,?,?)";
300299

301-
try (Connection conn = dataSource.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) {
300+
try(PreparedStatement ps = conn.prepareStatement(sql)) {
302301
CasbinRule line = savePolicyLine(ptype, rule);
303302

304303
ps.setString(1, line.ptype);
@@ -309,7 +308,6 @@ public void addPolicy(String sec, String ptype, List<String> rule) {
309308
ps.setString(6, line.v4);
310309
ps.setString(7, line.v5);
311310
ps.addBatch();
312-
313311
ps.executeBatch();
314312
} catch (SQLException e) {
315313
e.printStackTrace();
@@ -340,7 +338,7 @@ public void removeFilteredPolicy(String sec, String ptype, int fieldIndex, Strin
340338
columnIndex++;
341339
}
342340

343-
try (Connection conn = dataSource.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) {
341+
try (PreparedStatement ps = conn.prepareStatement(sql)) {
344342
ps.setString(1, ptype);
345343
for (int j = 0; j < values.size(); j++) {
346344
ps.setString(j + 2, values.get(j));
@@ -354,4 +352,11 @@ public void removeFilteredPolicy(String sec, String ptype, int fieldIndex, Strin
354352
throw new Error(e);
355353
}
356354
}
355+
356+
/**
357+
* Close the Connection.
358+
*/
359+
public void close() throws SQLException {
360+
conn.close();
361+
}
357362
}

src/main/java/org/casbin/adapter/JDBCDataSource.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.sql.SQLFeatureNotSupportedException;
2323
import java.util.logging.Logger;
2424

25-
2625
public class JDBCDataSource implements DataSource {
2726
private String driver;
2827
private String url;
@@ -64,7 +63,7 @@ public PrintWriter getLogWriter() throws SQLException {
6463
}
6564

6665
@Override
67-
public void setLogWriter(PrintWriter out) throws SQLException {
66+
public void setLogWriter(PrintWriter out) throws SQLException{
6867

6968
}
7069

src/test/java/org/casbin/adapter/JDBCAdapterTest.java

+25
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.junit.Test;
1818

19+
import java.sql.SQLException;
1920
import java.util.ArrayList;
2021
import java.util.List;
2122

@@ -43,6 +44,14 @@ public void testMySQLAdapter() {
4344
}
4445

4546
testAdapter(adapters);
47+
48+
adapters.forEach(adapter -> {
49+
try {
50+
adapter.close();
51+
} catch (SQLException sqlException) {
52+
sqlException.printStackTrace();
53+
}
54+
});
4655
}
4756

4857
@Test
@@ -59,6 +68,14 @@ public void testPgAdapter() {
5968
}
6069

6170
testAdapter(adapters);
71+
72+
adapters.forEach(adapter -> {
73+
try {
74+
adapter.close();
75+
} catch (SQLException sqlException) {
76+
sqlException.printStackTrace();
77+
}
78+
});
6279
}
6380

6481
@Test
@@ -75,5 +92,13 @@ public void testSQLServerAdapter() {
7592
}
7693

7794
testAdapter(adapters);
95+
96+
adapters.forEach(adapter -> {
97+
try {
98+
adapter.close();
99+
} catch (SQLException sqlException) {
100+
sqlException.printStackTrace();
101+
}
102+
});
78103
}
79104
}

0 commit comments

Comments
 (0)