Mercurial Hosting > nabble
view src/nabble/model/Db.java @ 63:4987e1a38a6c
remove ads from homepage
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 28 Aug 2024 15:34:42 -0600 |
parents | 7ecd1a4ef557 |
children |
line wrap: on
line source
/* Copyright (C) 2003 Franklin Schmidt <frank@gustos.com> */ package nabble.model; import fschmidt.db.DbArcana; import fschmidt.db.DbDatabase; import fschmidt.db.DbFinder; import fschmidt.db.util.WeakCacheMap; import fschmidt.util.java.Computable; import fschmidt.util.java.SimpleCache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; import java.util.Map; public final class Db { private static final Logger logger = LoggerFactory.getLogger(Db.class); static final String url = (String)Init.get("dbUrl"); static final String user = (String)Init.get("dbUser"); static final String password = (String)Init.get("dbPassword"); private static final long idleTimeout = Init.get("idleTimeout",5*60*1000L); static final String completeUrl = url + "?user=" + user + "&password=" + password; private static final DbDatabase baseDb = DbFinder.getBaseDatabase(url,user,password); private static final fschmidt.db.pool.Pool pool = new fschmidt.db.pool.Pool(); static { pool.setIdleTimeout(idleTimeout); } private static final class NoUserException extends SQLException { NoUserException(SQLException e) { super(e); } } static Connection getNativeConnection() { return pool.getNativeConnection(); } static void checkUser(String user) { try { Connection con = baseDb.getConnection(); Statement stmt = con.createStatement(); try { stmt.executeUpdate( "set role " + user ); } catch(SQLException e) { stmt.executeUpdate( "create user " + user + " with password '" + password + "'" ); stmt.executeUpdate( "set role " + user ); } stmt.close(); con.close(); } catch(SQLException e) { throw new RuntimeException("check user failed for: "+user,e); } } static class NoSchema extends RuntimeException { private NoSchema(String msg) { super(msg); } } private static void checkSchema(String schema) { try { Connection con = dbPostgres.getConnection(); Statement stmt = con.createStatement(); try { stmt.executeQuery( "select * from "+schema+".version" ); } catch(SQLException e) { if( e.getMessage().contains("does not exist") ) throw new NoSchema(schema); throw e; } finally { stmt.close(); con.close(); } } catch(SQLException e) { throw new RuntimeException("check schema failed for: "+schema,e); } } static DbDatabase pooledDb(String user) { return new fschmidt.db.pool.DbDatabaseImpl(baseDb,pool,user); } private static DbDatabase getDb(String user) { DbDatabase pooledDb = pooledDb(user); DbDatabase db = new fschmidt.db.cache.DbDatabaseImpl(pooledDb); if( !user.equals(Db.user) ) { checkSchema(user); try { DbSiteUpdater.update(user,db); } catch(UpdatingException e) { throw e; } catch(RuntimeException e) { throw new RuntimeException("couldn't update db for: "+user,e); } catch(SQLException e) { throw new RuntimeException("couldn't update db for: "+user,e); } } return db; } private static final DbDatabase dbPostgres = getDb(user); public static final DbArcana arcana = dbPostgres.arcana(); private static SimpleCache<String,DbDatabase> cache = new SimpleCache<String,DbDatabase>(new WeakCacheMap<String,DbDatabase>(), new Computable<String,DbDatabase>() { public DbDatabase get(String user) { return getDb(user); } }); static void uncache(String user) { cache.remove(user); } static DbDatabase db(String user) { return cache.get(user); } public static DbDatabase dbPostgres() { return dbPostgres; } public static DbDatabase dbGlobal() { return db("global"); } public static void clearCache() { fschmidt.db.cache.DbDatabaseImpl.clearCache(); } public static void main(String[] args) throws Exception { Connection con = dbPostgres.getConnection(); Statement stmt = con.createStatement(); for( String arg : args ) { stmt.executeUpdate(arg); } stmt.close(); con.close(); } private Db() {} // never }