package com.revolsys.gis.postgresql; import java.io.PrintWriter; import java.util.List; import com.revolsys.datatype.DataType; import com.revolsys.datatype.DataTypes; import com.revolsys.geometry.cs.CoordinateSystem; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.identifier.Identifier; import com.revolsys.io.PathUtil; import com.revolsys.jdbc.JdbcUtils; import com.revolsys.jdbc.io.JdbcDdlWriter; import com.revolsys.record.Record; import com.revolsys.record.property.FieldProperties; import com.revolsys.record.property.ShortNameProperty; import com.revolsys.record.schema.FieldDefinition; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.util.Property; public class PostgreSQLDdlWriter extends JdbcDdlWriter { public PostgreSQLDdlWriter() { } public PostgreSQLDdlWriter(final PrintWriter out) { super(out); } @Override public String getSequenceName(final RecordDefinition recordDefinition) { final String typePath = recordDefinition.getPath(); final String schema = JdbcUtils.getSchemaName(typePath); final ShortNameProperty shortNameProperty = ShortNameProperty.getProperty(recordDefinition); String shortName = null; if (shortNameProperty != null) { shortName = shortNameProperty.getShortName(); } if (Property.hasValue(shortName) && shortNameProperty.isUseForSequence()) { final String sequenceName = schema + "." + shortName.toLowerCase() + "_seq"; return sequenceName; } else { final String tableName = PathUtil.getName(typePath).toLowerCase(); final String idFieldName = recordDefinition.getIdFieldName().toLowerCase(); return schema + "." + tableName + "_" + idFieldName + "_seq"; } } public void writeAddGeometryColumn(final RecordDefinition recordDefinition) { final PrintWriter out = getOut(); final String typePath = recordDefinition.getPath(); String schemaName = JdbcUtils.getSchemaName(typePath); if (schemaName.length() == 0) { schemaName = "public"; } final String tableName = PathUtil.getName(typePath); final FieldDefinition geometryField = recordDefinition.getGeometryField(); if (geometryField != null) { final GeometryFactory geometryFactory = geometryField .getProperty(FieldProperties.GEOMETRY_FACTORY); final String name = geometryField.getName(); String geometryType = "GEOMETRY"; final DataType dataType = geometryField.getDataType(); if (dataType == DataTypes.POINT) { geometryType = "POINT"; } else if (dataType == DataTypes.LINE_STRING) { geometryType = "LINESTRING"; } else if (dataType == DataTypes.POLYGON) { geometryType = "POLYGON"; } else if (dataType == DataTypes.MULTI_POINT) { geometryType = "MULTIPOINT"; } else if (dataType == DataTypes.MULTI_LINE_STRING) { geometryType = "MULTILINESTRING"; } else if (dataType == DataTypes.MULTI_POLYGON) { geometryType = "MULTIPOLYGON"; } out.print("select addgeometrycolumn('"); out.print(schemaName.toLowerCase()); out.print("', '"); out.print(tableName.toLowerCase()); out.print("','"); out.print(name.toLowerCase()); out.print("',"); final CoordinateSystem coordinateSystem = geometryFactory.getCoordinateSystem(); out.print(coordinateSystem.getCoordinateSystemId()); out.print(",'"); out.print(geometryType); out.print("', "); out.print(geometryFactory.getAxisCount()); out.println(");"); } } public void writeAlterOwner(final String objectType, final String objectName, final String owner) { final PrintWriter out = getOut(); out.print("ALTER "); out.print(objectType); out.print(" "); out.print(objectName); out.print(" OWNER TO "); out.print(owner); out.println(";"); } public void writeAlterTableOwner(final String typePath, final String owner) { final PrintWriter out = getOut(); out.print("ALTER "); final String objectType = "TABLE"; out.print(objectType); out.print(" "); writeTableName(typePath); out.print(" OWNER TO "); out.print(owner); out.println(";"); } @Override public void writeColumnDataType(final FieldDefinition attribute) { final PrintWriter out = getOut(); final DataType dataType = attribute.getDataType(); if (dataType == DataTypes.BOOLEAN) { out.print("boolean"); } else if (dataType == DataTypes.BYTE) { out.print("NUMBER(3)"); } else if (dataType == DataTypes.SHORT) { out.print("smallint"); } else if (dataType == DataTypes.INT) { out.print("integer"); } else if (dataType == DataTypes.LONG) { out.print("bigint"); } else if (dataType == DataTypes.FLOAT) { out.print("real"); } else if (dataType == DataTypes.DOUBLE) { out.print("double precision"); } else if (dataType == DataTypes.DATE) { out.print("date"); } else if (dataType == DataTypes.DATE_TIME) { out.print("timestamp"); } else if (dataType == DataTypes.INTEGER) { out.print("NUMERIC("); out.print(attribute.getLength()); out.print(')'); } else if (dataType == DataTypes.DECIMAL) { out.print("NUMERIC("); out.print(attribute.getLength()); final int scale = attribute.getScale(); if (scale >= 0) { out.print(','); out.print(scale); } out.print(')'); } else if (dataType == DataTypes.STRING) { out.print("varchar("); out.print(attribute.getLength()); out.print(")"); } else if (Geometry.class.isAssignableFrom(dataType.getJavaClass())) { out.print("geometry"); } else { throw new IllegalArgumentException("Unknown data type " + dataType); } } @Override public void writeCreateSchema(final String schemaName) { final PrintWriter out = getOut(); out.print("CREATE SCHEMA "); out.print(schemaName); out.println(";"); } @Override public void writeGeometryRecordDefinition(final RecordDefinition recordDefinition) { final PrintWriter out = getOut(); final String typePath = recordDefinition.getPath(); String schemaName = JdbcUtils.getSchemaName(typePath); if (schemaName.length() == 0) { schemaName = "public"; } final String tableName = PathUtil.getName(typePath); final FieldDefinition geometryField = recordDefinition.getGeometryField(); if (geometryField != null) { final GeometryFactory geometryFactory = geometryField .getProperty(FieldProperties.GEOMETRY_FACTORY); final String name = geometryField.getName(); String geometryType = "GEOMETRY"; final DataType dataType = geometryField.getDataType(); if (dataType == DataTypes.POINT) { geometryType = "POINT"; } else if (dataType == DataTypes.LINE_STRING) { geometryType = "LINESTRING"; } else if (dataType == DataTypes.POLYGON) { geometryType = "POLYGON"; } else if (dataType == DataTypes.MULTI_POINT) { geometryType = "MULTIPOINT"; } else if (dataType == DataTypes.MULTI_LINE_STRING) { geometryType = "MULTILINESTRING"; } else if (dataType == DataTypes.MULTI_POLYGON) { geometryType = "MULTIPOLYGON"; } out.print( "INSERT INTO geometry_columns(f_table_catalog, f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, \"type\") VALUES ('','"); out.print(schemaName.toLowerCase()); out.print("', '"); out.print(tableName.toLowerCase()); out.print("','"); out.print(name.toLowerCase()); out.print("', "); out.print(geometryFactory.getAxisCount()); out.print(","); final CoordinateSystem coordinateSystem = geometryFactory.getCoordinateSystem(); out.print(coordinateSystem.getCoordinateSystemId()); out.print(",'"); out.print(geometryType); out.println("');"); } } @Override public void writeResetSequence(final RecordDefinition recordDefinition, final List<Record> values) { final PrintWriter out = getOut(); Long nextValue = 0L; for (final Record object : values) { final Identifier id = object.getIdentifier(); for (final Object value : id.getValues()) { if (value instanceof Number) { final Number number = (Number)value; final long longValue = number.longValue(); if (longValue > nextValue) { nextValue = longValue; } } } } nextValue++; final String sequeneName = getSequenceName(recordDefinition); out.print("ALTER SEQUENCE "); out.print(sequeneName); out.print(" RESTART WITH "); out.print(nextValue); out.println(";"); } }