001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/tools/datastore/PostGISDDLGenerator.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.tools.datastore; 037 038 import java.io.IOException; 039 import java.net.MalformedURLException; 040 import java.net.URL; 041 import java.util.ArrayList; 042 import java.util.Collection; 043 import java.util.Iterator; 044 import java.util.List; 045 046 import org.deegree.datatypes.Types; 047 import org.deegree.datatypes.UnknownTypeException; 048 import org.deegree.framework.xml.XMLParsingException; 049 import org.deegree.framework.xml.schema.XMLSchemaException; 050 import org.deegree.model.crs.UnknownCRSException; 051 import org.xml.sax.SAXException; 052 053 /** 054 * Generator for PostGIS DDL (CREATE / DROP) operations to create PostGIS database schemas from annotated GML schema 055 * files. 056 * 057 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a> 058 * @author last edited by: $Author: mschneider $ 059 * 060 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 061 */ 062 public class PostGISDDLGenerator extends DDLGenerator { 063 064 /** 065 * Generates a new instance of <code>PostGISDDLGenerator</code>, ready to generate DDL for the given schema. 066 * 067 * @param schemaURL 068 * @throws MalformedURLException 069 * @throws IOException 070 * @throws SAXException 071 * @throws XMLParsingException 072 * @throws XMLSchemaException 073 * @throws UnknownCRSException 074 */ 075 public PostGISDDLGenerator( URL schemaURL ) throws MalformedURLException, IOException, SAXException, 076 XMLParsingException, XMLSchemaException, UnknownCRSException { 077 super( schemaURL ); 078 } 079 080 @Override 081 protected StringBuffer generateSetSchemaStmt( String dbSchema ) { 082 StringBuffer sb = new StringBuffer( "SET search_path TO " ); 083 sb.append( dbSchema ); 084 sb.append( ",public;\n" ); 085 return sb; 086 } 087 088 @Override 089 protected StringBuffer generateCreateTableStmt( TableDefinition table ) { 090 091 List<ColumnDefinition> geometryColumns = new ArrayList<ColumnDefinition>(); 092 StringBuffer sb = new StringBuffer( "CREATE TABLE " ); 093 sb.append( table.getName() ); 094 sb.append( '(' ); 095 ColumnDefinition[] columns = table.getColumns(); 096 boolean needComma = false; 097 098 if ( table.getType() == MULTI_PROPERTY_TABLE ) { 099 sb.append( "\n " ); 100 sb.append( "PK SERIAL" ); 101 needComma = true; 102 } 103 104 for ( int i = 0; i < columns.length; i++ ) { 105 if ( !columns[i].isGeometry() ) { 106 if ( needComma ) { 107 sb.append( ',' ); 108 } else { 109 needComma = true; 110 } 111 sb.append( "\n " ); 112 sb.append( columns[i].getName() ); 113 sb.append( ' ' ); 114 String typeName; 115 try { 116 typeName = Types.getTypeNameForSQLTypeCode( columns[i].getType() ); 117 if ( typeName.equals( "DOUBLE" ) ) { 118 typeName = "DOUBLE PRECISION"; 119 } 120 } catch ( UnknownTypeException e ) { 121 typeName = "" + columns[i].getType(); 122 } 123 sb.append( typeName ); 124 if ( !columns[i].isNullable() ) { 125 sb.append( " NOT NULL" ); 126 } 127 } else { 128 geometryColumns.add( columns[i] ); 129 } 130 } 131 132 // add primary key information (forces index generation) 133 ColumnDefinition[] pkColumns = table.getPKColumns(); 134 if ( pkColumns.length > 0 ) { 135 sb.append( ",\n PRIMARY KEY (" ); 136 for ( int i = 0; i < pkColumns.length; i++ ) { 137 sb.append( pkColumns[i].getName() ); 138 if ( i != pkColumns.length - 1 ) { 139 sb.append( ',' ); 140 } 141 } 142 sb.append( ")\n);\n" ); 143 } else { 144 sb.append( "\n);\n" ); 145 } 146 147 // build addGeometryColumn() statements 148 for ( int i = 0; i < geometryColumns.size(); i++ ) { 149 ColumnDefinition column = geometryColumns.get( i ); 150 sb.append( "SELECT AddGeometryColumn ('', '" ); 151 sb.append( table.getName().toLowerCase() ); 152 sb.append( "', '" ); 153 sb.append( column.getName().toLowerCase() ); 154 sb.append( "', " ); 155 sb.append( column.getSRS() ); 156 sb.append( ", '" ); 157 sb.append( "GEOMETRY" ); 158 sb.append( "', '2');\n" ); 159 } 160 return sb; 161 } 162 163 @Override 164 protected StringBuffer generateCreateIndexStmts( TableDefinition table ) { 165 StringBuffer sb = new StringBuffer(); 166 167 // build create statements for spatial indexes 168 Collection<ColumnDefinition> geometryColumns = new ArrayList<ColumnDefinition>(); 169 for ( ColumnDefinition column : table.getColumns() ) { 170 if ( column.isGeometry() ) { 171 geometryColumns.add( column ); 172 } 173 } 174 175 Iterator<ColumnDefinition> iter = geometryColumns.iterator(); 176 int spatialIdxCnt = 1; 177 while ( iter.hasNext() ) { 178 ColumnDefinition column = iter.next(); 179 sb.append( "CREATE INDEX " ); 180 sb.append( table.getName() + ( spatialIdxCnt++ ) ); 181 sb.append( "_SPATIAL_IDX ON " ); 182 sb.append( table.getName() ); 183 sb.append( " USING GIST ( " ); 184 sb.append( column.getName() ); 185 sb.append( " GIST_GEOMETRY_OPS );" ); 186 sb.append( '\n' ); 187 } 188 189 // build create statements for indexes on all fk columns 190 ColumnDefinition[] columns = table.getColumns(); 191 for ( int i = 0; i < columns.length; i++ ) { 192 if ( columns[i].isFK() ) { 193 sb.append( "CREATE INDEX " ); 194 sb.append( table.getName() ); 195 sb.append( '_' ); 196 sb.append( columns[i].getName() ); 197 sb.append( "_IDX ON " ); 198 sb.append( table.getName() ); 199 sb.append( '(' ); 200 sb.append( columns[i].getName() ); 201 sb.append( ");\n" ); 202 } 203 } 204 205 return sb; 206 } 207 208 @Override 209 protected StringBuffer generateDropTableStmt( TableDefinition table ) { 210 StringBuffer sb = new StringBuffer(); 211 for ( ColumnDefinition column : table.getColumns() ) { 212 if ( column.isGeometry() ) { 213 sb.append( "SELECT DropGeometryColumn ('','" ); 214 sb.append( table.getName().toLowerCase() ); 215 sb.append( "', '" ); 216 sb.append( column.getName().toLowerCase() ); 217 sb.append( "');\n" ); 218 } 219 } 220 sb.append( super.generateDropTableStmt( table ) ); 221 return sb; 222 } 223 }