comparison src/nabble/model/Db.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1 /*
2
3 Copyright (C) 2003 Franklin Schmidt <frank@gustos.com>
4
5 */
6
7 package nabble.model;
8
9 import fschmidt.db.DbArcana;
10 import fschmidt.db.DbDatabase;
11 import fschmidt.db.DbFinder;
12 import fschmidt.db.util.WeakCacheMap;
13 import fschmidt.util.java.Computable;
14 import fschmidt.util.java.SimpleCache;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18 import java.sql.Connection;
19 import java.sql.PreparedStatement;
20 import java.sql.SQLException;
21 import java.sql.Statement;
22 import java.util.HashMap;
23 import java.util.Map;
24
25
26 public final class Db {
27 private static final Logger logger = LoggerFactory.getLogger(Db.class);
28 static final String url = (String)Init.get("dbUrl");
29 static final String user = (String)Init.get("dbUser");
30 static final String password = (String)Init.get("dbPassword");
31 private static final long idleTimeout = Init.get("idleTimeout",5*60*1000L);
32
33 static final String completeUrl = url + "?user=" + user + "&password=" + password;
34
35 private static final DbDatabase baseDb = DbFinder.getBaseDatabase(url,user,password);
36 private static final fschmidt.db.pool.Pool pool = new fschmidt.db.pool.Pool();
37 static {
38 pool.setIdleTimeout(idleTimeout);
39 }
40
41 private static final class NoUserException extends SQLException {
42 NoUserException(SQLException e) {
43 super(e);
44 }
45 }
46
47 static Connection getNativeConnection() {
48 return pool.getNativeConnection();
49 }
50
51 static void checkUser(String user) {
52 try {
53 Connection con = baseDb.getConnection();
54 Statement stmt = con.createStatement();
55 try {
56 stmt.executeUpdate(
57 "set role " + user
58 );
59 } catch(SQLException e) {
60 stmt.executeUpdate(
61 "create user " + user + " with password '" + password + "'"
62 );
63 stmt.executeUpdate(
64 "set role " + user
65 );
66 }
67 stmt.close();
68 con.close();
69 } catch(SQLException e) {
70 throw new RuntimeException("check user failed for: "+user,e);
71 }
72 }
73
74 static class NoSchema extends RuntimeException {
75 private NoSchema(String msg) {
76 super(msg);
77 }
78 }
79
80 private static void checkSchema(String schema) {
81 try {
82 Connection con = dbPostgres.getConnection();
83 Statement stmt = con.createStatement();
84 try {
85 stmt.executeQuery(
86 "select * from "+schema+".version"
87 );
88 } catch(SQLException e) {
89 if( e.getMessage().contains("does not exist") )
90 throw new NoSchema(schema);
91 throw e;
92 } finally {
93 stmt.close();
94 con.close();
95 }
96 } catch(SQLException e) {
97 throw new RuntimeException("check schema failed for: "+schema,e);
98 }
99 }
100
101 static DbDatabase pooledDb(String user) {
102 return new fschmidt.db.pool.DbDatabaseImpl(baseDb,pool,user);
103 }
104
105 private static DbDatabase getDb(String user) {
106 DbDatabase pooledDb = pooledDb(user);
107 DbDatabase db = new fschmidt.db.cache.DbDatabaseImpl(pooledDb);
108 if( !user.equals(Db.user) ) {
109 checkSchema(user);
110 try {
111 DbSiteUpdater.update(user,db);
112 } catch(UpdatingException e) {
113 throw e;
114 } catch(RuntimeException e) {
115 throw new RuntimeException("couldn't update db for: "+user,e);
116 } catch(SQLException e) {
117 throw new RuntimeException("couldn't update db for: "+user,e);
118 }
119 }
120 return db;
121 }
122
123 private static final DbDatabase dbPostgres = getDb(user);
124 public static final DbArcana arcana = dbPostgres.arcana();
125
126 private static SimpleCache<String,DbDatabase> cache = new SimpleCache<String,DbDatabase>(new WeakCacheMap<String,DbDatabase>(), new Computable<String,DbDatabase>() {
127 public DbDatabase get(String user) {
128 return getDb(user);
129 }
130 });
131
132 static void uncache(String user) {
133 cache.remove(user);
134 }
135
136 static DbDatabase db(String user) {
137 return cache.get(user);
138 }
139
140 public static DbDatabase dbPostgres() {
141 return dbPostgres;
142 }
143
144 public static DbDatabase dbGlobal() {
145 return db("global");
146 }
147
148 public static void clearCache() {
149 fschmidt.db.cache.DbDatabaseImpl.clearCache();
150 }
151
152
153 public static void main(String[] args) throws Exception {
154 Connection con = dbPostgres.getConnection();
155 Statement stmt = con.createStatement();
156 for( String arg : args ) {
157 stmt.executeUpdate(arg);
158 }
159 stmt.close();
160 con.close();
161 }
162
163 private Db() {} // never
164 }