Strabon

changeset 654:ce586092b475 temporals

added the respective class for PeriodTable
author Konstantina Bereta <Konstantina.Bereta@di.uoa.gr>
date Wed Oct 24 17:21:22 2012 +0300 (2012-10-24)
parents 413e2e0f4b4b
children 912d14f9ce47
files generaldb/src/main/java/org/openrdf/sail/generaldb/schema/PeriodTable.java
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/generaldb/src/main/java/org/openrdf/sail/generaldb/schema/PeriodTable.java	Wed Oct 24 17:21:22 2012 +0300
     1.3 @@ -0,0 +1,419 @@
     1.4 +package org.openrdf.sail.generaldb.schema;
     1.5 +
     1.6 +import java.sql.PreparedStatement;
     1.7 +import java.sql.ResultSet;
     1.8 +import java.sql.SQLException;
     1.9 +import java.sql.Types;
    1.10 +import java.util.ArrayList;
    1.11 +import java.util.List;
    1.12 +import java.util.concurrent.BlockingQueue;
    1.13 +
    1.14 +import org.openrdf.sail.generaldb.GeneralDBSqlTable;
    1.15 +import org.openrdf.sail.rdbms.schema.RdbmsTable;
    1.16 +
    1.17 +/**
    1.18 + * Modified to be used with a valid time-enabled table
    1.19 + *
    1.20 + * Manages the rows in a value table. These tables have two columns: an internal
    1.21 + * id column and a value (PERIOD) column
    1.22 + * 
    1.23 + * @author James Leigh
    1.24 + * @author Konstantina Bereta
    1.25 + * 
    1.26 + */
    1.27 +
    1.28 +public class PeriodTable {
    1.29 +	public static int BATCH_SIZE = 8 * 1024;
    1.30 +
    1.31 +	public static final long NIL_ID = 0; // TODO
    1.32 +
    1.33 +	private static final String[] PKEY = { "id" };
    1.34 +
    1.35 +	//used to be named "value"
    1.36 +	//private static final String[] VALUE_INDEX = { "original" };
    1.37 +
    1.38 +	//private static final String[] MINIMUM_BOUNDING_BOX = { "value" };
    1.39 +
    1.40 +	private static final String[] CONSTRAINT = { "constr" };
    1.41 +
    1.42 +	private int length = -1;
    1.43 +
    1.44 +	private int sqlType;
    1.45 +
    1.46 +	private int idType;
    1.47 +
    1.48 +	private String INSERT;
    1.49 +
    1.50 +	private String INSERT_SELECT;
    1.51 +
    1.52 +	private String EXPUNGE;
    1.53 +
    1.54 +	private RdbmsTable table;
    1.55 +
    1.56 +	private RdbmsTable temporary;
    1.57 +
    1.58 +	private ValueBatch batch;
    1.59 +
    1.60 +	private BlockingQueue<Batch> queue;
    1.61 +
    1.62 +	private boolean indexingValues;
    1.63 +
    1.64 +	private PreparedStatement insertSelect;
    1.65 +
    1.66 +	public void setQueue(BlockingQueue<Batch> queue) {
    1.67 +		this.queue = queue;
    1.68 +	}
    1.69 +
    1.70 +	public boolean isIndexingValues() {
    1.71 +		return indexingValues;
    1.72 +	}
    1.73 +
    1.74 +	public void setIndexingValues(boolean indexingValues) {
    1.75 +		this.indexingValues = indexingValues;
    1.76 +	}
    1.77 +
    1.78 +	public int getLength() {
    1.79 +		return length;
    1.80 +	}
    1.81 +
    1.82 +	public void setLength(int length) {
    1.83 +		this.length = length;
    1.84 +	}
    1.85 +
    1.86 +	public int getSqlType() {
    1.87 +		return sqlType;
    1.88 +	}
    1.89 +
    1.90 +	public void setSqlType(int sqlType) {
    1.91 +		this.sqlType = sqlType;
    1.92 +	}
    1.93 +
    1.94 +	public int getIdType() {
    1.95 +		return idType;
    1.96 +	}
    1.97 +
    1.98 +	public void setIdType(int sqlType) {
    1.99 +		this.idType = sqlType;
   1.100 +	}
   1.101 +
   1.102 +	public RdbmsTable getRdbmsTable() {
   1.103 +		return table;
   1.104 +	}
   1.105 +
   1.106 +	public void setRdbmsTable(RdbmsTable table) {
   1.107 +		this.table = table;
   1.108 +	}
   1.109 +
   1.110 +	public RdbmsTable getTemporaryTable() {
   1.111 +		return temporary;
   1.112 +	}
   1.113 +
   1.114 +	public void setTemporaryTable(RdbmsTable temporary) {
   1.115 +		this.temporary = temporary;
   1.116 +	}
   1.117 +
   1.118 +	public String getName() {
   1.119 +		return table.getName();
   1.120 +	}
   1.121 +
   1.122 +	public long size() {
   1.123 +		return table.size();
   1.124 +	}
   1.125 +
   1.126 +	public int getBatchSize() {
   1.127 +		return BATCH_SIZE;
   1.128 +	}
   1.129 +
   1.130 +	//FIXME temporal additions
   1.131 +	public void initialize()
   1.132 +	throws SQLException
   1.133 +	{
   1.134 +		StringBuilder sb = new StringBuilder();
   1.135 +		sb.append("INSERT INTO ").append(getInsertTable().getName());
   1.136 +//		sb.append(((GeneralDBSqlTable)table).buildInsertGeometryValue());
   1.137 +		INSERT = sb.toString();
   1.138 +		sb.delete(0, sb.length());
   1.139 +		sb.append("DELETE FROM ").append(table.getName()).append("\n");
   1.140 +		sb.append(((GeneralDBSqlTable)table).buildWhere());
   1.141 +		EXPUNGE = sb.toString();
   1.142 +		if (temporary != null) {
   1.143 +			sb.delete(0, sb.length());
   1.144 +			sb.append("INSERT INTO ").append(table.getName());
   1.145 +			sb.append(" (id, period) SELECT DISTINCT id, period FROM ");
   1.146 +			sb.append(temporary.getName()).append(" tmp\n");
   1.147 +			sb.append("WHERE NOT EXISTS (SELECT id FROM ").append(table.getName());
   1.148 +			sb.append(" val WHERE val.id = tmp.id)");
   1.149 +			INSERT_SELECT = sb.toString();
   1.150 +		}
   1.151 +		if (!table.isCreated()) {
   1.152 +			createTable(table);
   1.153 +			table.primaryIndex(PKEY);
   1.154 +		}
   1.155 +		else {
   1.156 +			table.count();
   1.157 +		}
   1.158 +		if (temporary != null && !temporary.isCreated()) {
   1.159 +			createTemporaryTable(temporary);
   1.160 +		}
   1.161 +	}
   1.162 +
   1.163 +	public void close()
   1.164 +	throws SQLException
   1.165 +	{
   1.166 +		if (insertSelect != null) {
   1.167 +			insertSelect.close();
   1.168 +		}
   1.169 +		if (temporary != null) {
   1.170 +			temporary.close();
   1.171 +		}
   1.172 +		table.close();
   1.173 +	}
   1.174 +
   1.175 +
   1.176 +	
   1.177 +
   1.178 +	public synchronized void insert(Number id, Integer srid, String period)
   1.179 +		throws SQLException, InterruptedException, NullPointerException
   1.180 +	{
   1.181 +
   1.182 +	
   1.183 +		ValueBatch batch = getValueBatch();
   1.184 +		if (isExpired(batch)) {
   1.185 +			batch = newValueBatch();
   1.186 +			initBatch(batch);
   1.187 +		}
   1.188 +		batch.setObject(1, id);
   1.189 +
   1.190 +		if(period.length() == 0)
   1.191 +		{
   1.192 +			batch.setObject(2,null); 
   1.193 +		}
   1.194 +		else
   1.195 +		{
   1.196 +			///
   1.197 +//			geom[0]=1;
   1.198 +//			String hexString = new String(Hex.encodeHex(geom));
   1.199 +//			System.err.println(id+", "+hexString);
   1.200 +			///
   1.201 +			batch.setObject(2,period);
   1.202 +		}
   1.203 +		batch.setObject(3, srid); //adding original srid-constant
   1.204 +		batch.setObject(4, srid);
   1.205 +		
   1.206 +		batch.addBatch();
   1.207 +		queue(batch);
   1.208 +
   1.209 +	}
   1.210 +	
   1.211 +
   1.212 +
   1.213 +	public ValueBatch getValueBatch() {
   1.214 +		return this.batch;
   1.215 +	}
   1.216 +
   1.217 +	public boolean isExpired(ValueBatch batch) {
   1.218 +		if (batch == null || batch.isFull())
   1.219 +			return true;
   1.220 +		return queue == null || !queue.remove(batch);
   1.221 +	}
   1.222 +
   1.223 +	public ValueBatch newValueBatch() {
   1.224 +		return new ValueBatch();
   1.225 +	}
   1.226 +
   1.227 +	public void initBatch(ValueBatch batch)
   1.228 +	throws SQLException
   1.229 +	{
   1.230 +		batch.setTable(table);
   1.231 +		batch.setBatchStatement(prepareInsert(INSERT));
   1.232 +		batch.setMaxBatchSize(getBatchSize());
   1.233 +		if (temporary != null) {
   1.234 +			batch.setTemporary(temporary);
   1.235 +			if (insertSelect == null) {
   1.236 +				insertSelect = prepareInsertSelect(INSERT_SELECT);
   1.237 +			}
   1.238 +			batch.setInsertStatement(insertSelect);
   1.239 +		}
   1.240 +	}
   1.241 +
   1.242 +	public void queue(ValueBatch batch)
   1.243 +	throws SQLException, InterruptedException
   1.244 +	{
   1.245 +		this.batch = batch;
   1.246 +		if (queue == null) {
   1.247 +			batch.flush();
   1.248 +		}
   1.249 +		else {
   1.250 +			queue.put(batch);
   1.251 +		}
   1.252 +	}
   1.253 +
   1.254 +	public void optimize()
   1.255 +	throws SQLException
   1.256 +	{
   1.257 +		table.optimize();
   1.258 +	}
   1.259 +
   1.260 +	public boolean expunge(String condition)
   1.261 +	throws SQLException
   1.262 +	{
   1.263 +		synchronized (table) {
   1.264 +			int count = table.executeUpdate(EXPUNGE + condition);
   1.265 +			if (count < 1)
   1.266 +				return false;
   1.267 +			table.modified(0, count);
   1.268 +			return true;
   1.269 +		}
   1.270 +	}
   1.271 +
   1.272 +	public List<Long> maxIds(int shift, int mod)
   1.273 +	throws SQLException
   1.274 +	{
   1.275 +		String column = "id";
   1.276 +		StringBuilder expr = new StringBuilder();
   1.277 +		expr.append("MOD((").append(column);
   1.278 +		expr.append(" >> ").append(shift);
   1.279 +		expr.append(") + ").append(mod).append(", ");
   1.280 +		expr.append(mod);
   1.281 +		expr.append(")");
   1.282 +		StringBuilder sb = new StringBuilder();
   1.283 +		sb.append("SELECT ");
   1.284 +		sb.append("MAX(");
   1.285 +		sb.append(column);
   1.286 +		sb.append("), ").append(expr).append(" AS grp");
   1.287 +		sb.append("\nFROM ").append(getName());
   1.288 +		sb.append("\nGROUP BY grp");
   1.289 +		String query = sb.toString();
   1.290 +		PreparedStatement st = table.prepareStatement(query);
   1.291 +		try {
   1.292 +			ResultSet rs = st.executeQuery();
   1.293 +			try {
   1.294 +				List<Long> result = new ArrayList<Long>();
   1.295 +				while (rs.next()) {
   1.296 +					result.add(rs.getLong(1));
   1.297 +				}
   1.298 +				return result;
   1.299 +			}
   1.300 +			finally {
   1.301 +				rs.close();
   1.302 +			}
   1.303 +		}
   1.304 +		finally {
   1.305 +			st.close();
   1.306 +		}
   1.307 +	}
   1.308 +	
   1.309 +	public String sqlWrapper(String type, int length){
   1.310 +		
   1.311 +		if(type.equalsIgnoreCase("period"))
   1.312 +			return "PERIOD";
   1.313 +		else return sql(Integer.parseInt(type), length);
   1.314 +	}
   1.315 +
   1.316 +	public String sql(int type, int length) {
   1.317 +		switch (type) {
   1.318 +		case Types.VARCHAR:
   1.319 +			if (length > 0)
   1.320 +				return "VARCHAR(" + length + ")";
   1.321 +			return "TEXT";
   1.322 +		case Types.LONGVARCHAR:
   1.323 +			if (length > 0)
   1.324 +				return "LONGVARCHAR(" + length + ")";
   1.325 +			return "TEXT";
   1.326 +		case Types.BIGINT:
   1.327 +			return "BIGINT";
   1.328 +		case Types.INTEGER:
   1.329 +			return "INTEGER";
   1.330 +		case Types.SMALLINT:
   1.331 +			return "SMALLINT";
   1.332 +		case Types.FLOAT:
   1.333 +			return "FLOAT";
   1.334 +		case Types.DOUBLE:
   1.335 +			return "DOUBLE";
   1.336 +		case Types.DECIMAL:
   1.337 +			return "DECIMAL";
   1.338 +		case Types.BOOLEAN:
   1.339 +			return "BOOLEAN";
   1.340 +		case Types.TIMESTAMP:
   1.341 +			return "TIMESTAMP";
   1.342 +			//FIXME my addition here	
   1.343 +		case Types.VARBINARY:
   1.344 +			//System.out.println("BYTE ARRAY NEEDED");
   1.345 +			return "BYTEA";
   1.346 +			//case 2112:
   1.347 +			//	System.out.println("Geometry NEEDED");
   1.348 +			//	return "GEOMETRY";
   1.349 +		default:
   1.350 +			throw new AssertionError("Unsupported SQL Type: " + type);
   1.351 +		}
   1.352 +	}
   1.353 +	
   1.354 +	
   1.355 +
   1.356 +	@Override
   1.357 +	public String toString() {
   1.358 +		return getName();
   1.359 +	}
   1.360 +
   1.361 +	protected RdbmsTable getInsertTable() {
   1.362 +		RdbmsTable tmp = getTemporaryTable();
   1.363 +		if (tmp == null) {
   1.364 +			tmp = getRdbmsTable();
   1.365 +		}
   1.366 +		return tmp;
   1.367 +	}
   1.368 +
   1.369 +	protected PreparedStatement prepareInsert(String sql)
   1.370 +	throws SQLException
   1.371 +	{
   1.372 +		return table.prepareStatement(sql);
   1.373 +	}
   1.374 +
   1.375 +	protected PreparedStatement prepareInsertSelect(String sql)
   1.376 +	throws SQLException
   1.377 +	{
   1.378 +		return table.prepareStatement(sql);
   1.379 +	}
   1.380 +
   1.381 +
   1.382 +	/**
   1.383 +	 * FIXME careful here 
   1.384 +	 * CURRENT FIELDS: id, value (byte[] form of Polyhedron, strdfgeo(wkt version of Polyhedron)
   1.385 +	 */
   1.386 +	protected void createTable(RdbmsTable table)
   1.387 +		throws SQLException
   1.388 +	{
   1.389 +		//TODO maybe later an additional column should be created to represent the time zone. BUT postgres temporal translates all 
   1.390 +		// timezone representation in GMT and stores them. When retrieved, they are all transformed into the timezone of the running machine
   1.391 +		StringBuilder sb = new StringBuilder();
   1.392 +		sb.append("  id ").append(sql(idType, -1)).append(" NOT NULL,");
   1.393 +		sb.append("  period ").append("PERIOD").append(" NOT NULL,");
   1.394 +	
   1.395 +		table.createTable(sb);
   1.396 +		
   1.397 +		String extension = ((GeneralDBSqlTable)table).buildGeometryCollumn();
   1.398 +		table.execute(extension);
   1.399 +		
   1.400 +		String index = ((GeneralDBSqlTable)table).buildIndexOnGeometryCollumn();
   1.401 +		table.execute(index);
   1.402 +	}
   1.403 +
   1.404 +	/**
   1.405 +	 * FIXME careful here - has not been tested
   1.406 +	 */
   1.407 +	protected void createTemporaryTable(RdbmsTable table)
   1.408 +	throws SQLException
   1.409 +	{
   1.410 +		StringBuilder sb = new StringBuilder();
   1.411 +		sb.append("  id ").append(sql(idType, -1)).append(" NOT NULL,");
   1.412 +		sb.append("  period ").append("PERIOD").append(" NOT NULL,"); //TODO use sqlWrapper to make this code more generic!
   1.413 +		table.createTemporaryTable(sb);
   1.414 +//		String extension = "SELECT AddGeometryColumn('','geo_values','value',32630,'GEOMETRY',2)";
   1.415 +		//TODO edw tha prepei na mpei index kai period column
   1.416 +		//String extension = ((GeneralDBSqlTable)table).buildGeometryCollumn();
   1.417 +		//table.execute(extension);
   1.418 +	}
   1.419 +}
   1.420 +	
   1.421 +
   1.422 +