/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.esl.sql.model; import java.util.ArrayList; import java.util.List; import com.enonic.cms.framework.jdbc.dialect.Dialect; /** * This class implements the database script generator. It does insert placeholders where database specific values should appear. */ public final class DatabaseSchemaTool { /** * Generate create foreign keys. */ public static List<String> generateCreateForeignKeys( Database db ) { List<String> list = new ArrayList<String>(); Table[] tables = db.getTables(); for ( int i = 0; i < tables.length; i++ ) { list.addAll( generateCreateForeignKeys( tables[i] ) ); } return list; } /** * Generate create foreign keys. */ public static List<String> generateCreateForeignKeys( Table table ) { List<String> list = new ArrayList<String>(); ForeignKey[] foreignKeys = table.getRealForeignKeys(); for ( int i = 0; i < foreignKeys.length; i++ ) { StringBuilder sql = new StringBuilder(); sql.append( "ALTER TABLE " ); sql.append( table ); sql.append( "\n\tADD CONSTRAINT " ); sql.append( foreignKeys[i].getName() ); sql.append( " FOREIGN KEY (" ); ForeignKey.Reference[] references = foreignKeys[i].getReferences(); for ( int j = 0; j < references.length; j++ ) { sql.append( references[j].localColumn ); if ( j < references.length - 1 ) { sql.append( ", " ); } } sql.append( ")\n\tREFERENCES " ); sql.append( foreignKeys[i].getRemoteTable() ); sql.append( "(" ); for ( int j = 0; j < references.length; j++ ) { sql.append( references[j].remoteColumn ); if ( j < references.length - 1 ) { sql.append( ", " ); } } sql.append( ") @updateRestrict@ @deleteRestrict@\n" ); list.add( sql.toString() ); } return list; } /** * /** * Generate create indexes. */ public static List<String> generateCreateIndexes( Database db ) { List<String> list = new ArrayList<String>(); Table[] tables = db.getTables(); for ( int i = 0; i < tables.length; i++ ) { list.addAll( generateCreateIndexes( tables[i] ) ); } return list; } /** * Generate create indexes. */ public static List<String> generateCreateIndexes( Table table ) { List<String> list = new ArrayList<String>(); Index[] indexes = table.getIndexes(); for ( int i = 0; i < indexes.length; i++ ) { StringBuilder sql = new StringBuilder(); sql.append( "CREATE " ); if ( indexes[i].isUnique() ) { sql.append( "UNIQUE " ); } sql.append( "INDEX " ); sql.append( indexes[i].getName() ); sql.append( " ON " ); sql.append( table ); sql.append( " (" ); List<Column> columns = indexes[i].getColumns(); for ( int j = 0; j < columns.size(); j++ ) { sql.append( columns.get( j ) ); if ( j < columns.size() - 1 ) { sql.append( ", " ); } } sql.append( ")" ); list.add( sql.toString() ); } return list; } /** * Generate create table. */ public static String generateCreateTable( Table table ) { StringBuilder sql = new StringBuilder(); sql.append( "CREATE TABLE " ); sql.append( table.getName() ); sql.append( " (\n" ); Column[] columns = table.getColumns(); for ( int i = 0; i < columns.length; i++ ) { sql.append( "\t" ); sql.append( columns[i].getName() ); sql.append( " " ); sql.append( Dialect.getTypePlaceholder( columns[i].getType().getSQLType(), columns[i].getSize() ) ); sql.append( " " ); sql.append( columns[i].isRequired() ? "@notNullable@" : "@nullable@" ); sql.append( ", \n" ); } sql.append( "\tprimary key (" ); Column[] pkColumns = table.getPrimaryKeys(); for ( int i = 0; i < pkColumns.length; i++ ) { sql.append( pkColumns[i].getName() ); if ( i < pkColumns.length - 1 ) { sql.append( ", " ); } } sql.append( ")\n)" ); return sql.toString(); } /** * Generate create view. */ public static String generateCreateView( View view ) { StringBuilder sql = new StringBuilder(); sql.append( "CREATE VIEW " ); sql.append( view.getName() ); sql.append( " (\n" ); Column[] columns = view.getColumns(); for ( int i = 0; i < columns.length; i++ ) { if ( i > 0 ) { sql.append( ", " ); } sql.append( columns[i].getName() ); } sql.append( ") as\n" ); sql.append( view.getSelectSql() ); return sql.toString(); } /** * Generate create tables. */ public static List<String> generateCreateTables( Database db ) { List<String> list = new ArrayList<String>(); Table[] tables = db.getTables(); for ( int i = 0; i < tables.length; i++ ) { list.add( generateCreateTable( tables[i] ) ); } return list; } /** * Generate create views. */ public static List<String> generateCreateViews( Database db ) { List<String> list = new ArrayList<String>(); View[] views = db.getViews(); for ( int i = 0; i < views.length; i++ ) { list.add( generateCreateView( views[i] ) ); } return list; } /** * Generate create views. */ public static List<String> generateDropViews( Database db ) { List<String> list = new ArrayList<String>(); View[] views = db.getViews(); /* Reverse order - views might be dependent on each other */ for ( int i = views.length; i != 0; i-- ) { list.add( "DROP VIEW " + views[i - 1].getName() ); } return list; } /** * Generate create database. */ public static List<String> generateDatabaseSchema( Database db ) { List<String> list = new ArrayList<String>(); list.addAll( generateCreateTables( db ) ); list.addAll( generateCreateForeignKeys( db ) ); list.addAll( generateCreateIndexes( db ) ); list.addAll( generateCreateViews( db ) ); list.addAll( db.getStatements() ); return list; } }