Mercurial Hosting > nabble
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 } |