private CommunityDAO() {
		
		// Create the Derby DB
		try
		{
			Class.forName(DRIVER);
		} 
		catch( ClassNotFoundException e )
		{
			logger.severe(e.toString());
		}

		try
		{
			StringBuilder connect = new StringBuilder();
			connect.append("jdbc:mysql://");
			connect.append(System.getProperty("db.host"));
			connect.append(System.getProperty("db.port") == null ? ":3306" : (":"+System.getProperty("db.port")));
			connect.append("/"+(System.getProperty("db.name")==null ? "community_db" : System.getProperty("db.name")));
//			connect.append("?user=" + System.getProperty("db.user"));
//			connect.append("&password=" + System.getProperty("db.password"));
			connect.append("?characterEncoding=UTF8&characterSetResults=UTF8&useUnicode=true");
			
			logger.finest("DB connect string: " + connect.toString());
//			con = DriverManager.getConnection(connect.toString());
			
			BoneCPConfig config = new BoneCPConfig();
			config.setJdbcUrl(connect.toString());
			
			config.setUsername(System.getProperty("db.user"));
			config.setPassword(System.getProperty("db.password"));
			
			config.setMinConnectionsPerPartition(5);
			config.setMaxConnectionsPerPartition(30);
			config.setPartitionCount(1);
			connectionPool = new BoneCP(config); 
		}
		catch( SQLException e )
		{
			logger.severe(e.toString());
			e.printStackTrace();
		}
		
//		drop_tables();
		check_create_tables();
		load();
		
		/**
		 * Remove old peers every hour. 
		 */
		(new Timer("prune old peers", true)).schedule(new TimerTask(){
			public void run() {
				
				if( System.getProperty(EXPIRATION_PROPERTY) != null ) {
					try {
						userTimeout = Long.parseLong(System.getProperty(EXPIRATION_PROPERTY)) * 1000;
						logger.info("Using user timeout: " + userTimeout + " seconds");
					} catch( Exception e ) {
						logger.warning("Invalid user expiration timeout: " + System.getProperty(EXPIRATION_PROPERTY));
					}
				}
				
				int removedDB = (new SQLStatementProcessor<Integer>("DELETE FROM registered_keys WHERE last_refresh_timestamp < ?") {
					Integer process(PreparedStatement s) throws SQLException {
						s.setTimestamp(1, new java.sql.Timestamp(System.currentTimeMillis() - userTimeout));
						int removed = s.executeUpdate();
						return removed;
					}
				}).doit();
				
				logger.info("Pruned " + removedDB + " old peers");
				
				load();
			}}, 1000, 15 * 60 * 1000);
		
		/**
		 * Drain the lazy DB queue
		 */
		Thread lazyDrain = new Thread("Lazy DB drainer") {
			public void run() {
				while( true ) {
					try {
						mLazyDBQueue.take().run();
					}catch( Exception e ) {
						e.printStackTrace();
						try {
							/**
							 * Slow down if bad things are happening
							 */
							Thread.sleep(100);
						} catch (InterruptedException e1) {}
					}
				}
			}
		};
		lazyDrain.setDaemon(true);
		lazyDrain.start();
	}