view src/luan/modules/sql/Database.java @ 1341:a015a0b5c388

add Html.decode(), Lucene.count_tokens(), lucene boosts, Sql.database.set()
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 19 Feb 2019 08:14:40 -0700
parents 8b61c8c4e07a
children 002152af497a
line wrap: on
line source

package luan.modules.sql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.HashMap;
import java.util.Properties;
import luan.lib.logging.Logger;
import luan.lib.logging.LoggerFactory;
import luan.Luan;
import luan.LuanTable;
import luan.LuanException;


public final class Database {
	private static final Logger logger = LoggerFactory.getLogger(Database.class);

	public final Connection con;
	private final Map<String,PreparedStatement> pstmts = new HashMap<String,PreparedStatement>();
	private int fetchSize = 0;

	public Database(Connection con) {
		this.con = con;
	}

	public Database(LuanTable specTbl)
		throws LuanException, ClassNotFoundException, SQLException
	{
		Map<Object,Object> spec = specTbl.asMap();
		String cls = getString(spec,"class");
		Class.forName(cls);
		String url = getString(spec,"url");
		Properties props = new Properties();
		props.putAll(spec);
		this.con = DriverManager.getConnection(url,props);
		set(spec);
	}

	public void set(LuanTable options) throws LuanException, SQLException {
		set(options.asMap());
	}

	private void set(Map<Object,Object> options) throws LuanException, SQLException {
		Object obj;
		obj = options.remove("auto_commit");
		if( obj != null ) {
			if( !(obj instanceof Boolean) )
				throw new LuanException( "parameter 'auto_commit' must be a boolean" );
			con.setAutoCommit((Boolean)obj);
		}
		obj = options.remove("fetch_size");
		if( obj != null ) {
			Integer n = Luan.asInteger(obj);
			if( n == null )
				throw new LuanException( "parameter 'fetch_size' must be an integer" );
			fetchSize = n;
		}
		if( !options.isEmpty() )
			throw new LuanException( "unrecognized parameters: "+options );
	}

	private static String getString(Map spec,String key) throws LuanException {
		Object val = spec.remove(key);
		if( val==null )
			throw new LuanException( "parameter '"+key+"' is required" );
		if( !(val instanceof String) )
			throw new LuanException( "parameter '"+key+"' must be a string" );
		return (String)val;
	}

	private void fix(Statement stmt) throws SQLException {
		if( fetchSize > 0 )
			stmt.setFetchSize(fetchSize);
	}

	private PreparedStatement prepareStatement(String sql,Object[] args) throws SQLException {
		PreparedStatement pstmt = pstmts.get(sql);
		if( pstmt==null ) {
			pstmt = con.prepareStatement(sql);
			fix(pstmt);
			pstmts.put(sql,pstmt);
		}
		for( int i=0; i<args.length; i++ ) {
			pstmt.setObject(i+1,args[i]);
		}
		return pstmt;
	}

	public ResultSet query(String sql,Object... args) throws SQLException {
		if( args.length == 0 ) {
			Statement stmt = con.createStatement();
			fix(stmt);
			return stmt.executeQuery(sql);
		} else {
			PreparedStatement pstmt = prepareStatement(sql,args);
			return pstmt.executeQuery();
		}
	}

	public int update(String sql,Object... args) throws SQLException {
		if( args.length == 0 ) {
			Statement stmt = con.createStatement();
			fix(stmt);
			int n = stmt.executeUpdate(sql);
			stmt.close();
			return n;
		} else {
			PreparedStatement pstmt = prepareStatement(sql,args);
			return pstmt.executeUpdate();
		}
	}

}