import java.sql.*;
import java.io.*;
import uk.ac.ic.doc.automed.*;
import uk.ac.ic.doc.automed.reps.*;
import java.util.*;
import uk.ac.ic.doc.automed.wrappers.*;
import uk.ac.bbk.dcs.automed.xml.wrappers.*;
import uk.ac.bbk.dcs.automed.xml.*;
import org.w3c.dom.Document;

/**
 * An application to demonstrate how to create schemas in existing models
 */
public class CoinsNotesCash {
  public static void wrapSchemas() 
    throws IntegrityException, DataSourceException, NotFoundException {
    AutoMedWrapper sw=AutoMedWrapper.
      selectNewAutoMedWrapper("lab","lab",null,null,
	"jdbc:postgresql://localhost/automed");
    SQLWrapperFactory wf=(SQLWrapperFactory)sw.getAutoMedWrapperFactory();
    wf.setFeatures(SQLWrapperFactory.PRIMARY_KEY);
    wf.setFeatures(SQLWrapperFactory.FOREIGN_KEY);
    //wf.setFeatures(SQLWrapperFactory.DATA_TYPE);
    //wf.setFeatures(SQLWrapperFactory.DATA_SIZE);
    wf.setFeatures(SQLWrapperFactory.NULL_CONSTRAINT);
    //wf.setFeatures(SQLWrapperFactory.SCHEMA_AWARE);
    //wf.setFeatures(SQLWrapperFactory.SCHEMA_MERGING);
    sw.setOption(SQLWrapper.OPTION_SCHEMA_NAME,"notes");
    //System.out.println("Set "+SQLWrapper.OPTION_SCHEMA_NAME+"+staff");
    Schema.retract("notes_src");
    sw.getSchema("notes_src");
    wf.createAutoMedSchema(sw,"notes");

    sw=AutoMedWrapper.
      selectNewAutoMedWrapper("lab","lab",null,null,
	"jdbc:postgresql://localhost/automed",null,wf); 

    sw.setOption(SQLWrapper.OPTION_SCHEMA_NAME,"coins");
    Schema.retract("coins_src");
    sw.getSchema("coins_src");
    wf.createAutoMedSchema(sw,"coins");

    sw=AutoMedWrapper.
      selectNewAutoMedWrapper("lab","lab",null,null,
	"jdbc:postgresql://localhost/automed",null,wf); 
    sw.setOption(SQLWrapper.OPTION_SCHEMA_NAME,"cash");
    Schema.retract("cash_src");
    sw.getSchema("cash_src");
    wf.createAutoMedSchema(sw,"cash");
 }

 public static void main(String[] args) 
   throws Exception {
   System.out.println("AutoMed Notes, Coins and Cash Example");

   wrapSchemas();
   
   // Add notes column to coins schema
   Schema coins=Schema.getSchema("coins");
   SchemaObject coins_branch=coins.getSchemaObject("<<branch>>");
   Construct table=coins_branch.getConstruct();
   Construct column=
     table.getModel().getConstruct(SQLWrapperFactory.
				   AUTOMED_SQL_MODEL_COLUMN);
   
   coins=coins.applyExtendTransformation(column,
	   new Object[]{coins_branch,"notes","notnull"},null,null);
   
   // Add coins column to notes schema
   Schema notes=Schema.getSchema("notes");
   SchemaObject notes_branch=notes.getSchemaObject("<<branch>>");
   
   notes=notes.applyExtendTransformation(column,
	   new Object[]{notes_branch,"coins","notnull"},null,null);
   
   // Add coins and notes to cash
   Schema cash=Schema.getSchema("cash");
   SchemaObject cash_branch=cash.getSchemaObject("<<branch>>");
   
   Schema cash2=cash.applyExtendTransformation(column,
	           new Object[]{cash_branch,"coins","notnull"},null,null);
   cash2=cash2.applyAddTransformation(column,
	           new Object[]{cash_branch,"notes","notnull"},
		   "[{b,ca-co} | {b,ca} <- <<branch,cash>>; "+
		   "{b,co} <- <<branch,coins>>]",null);
   cash=cash.applyExtendTransformation(column,
	           new Object[]{cash_branch,"notes","notnull"},null,null);
   cash=cash.applyAddTransformation(column,
	           new Object[]{cash_branch,"coins","notnull"},
		   "[{b,ca-n} | {b,ca} <- <<branch,cash>>; "+
		   "{b,n} <- <<branch,notes>>]",null);

   Transformation.createIdentTransformation(cash,cash2,null,null);
   SchemaObject branchcash=cash.getSchemaObject("<<branch,cash>>");
   cash=cash.applyDeleteTransformation(branchcash,
		   "[{b,co+n} | {b,co} <- <<branch,coins>>; "+
		   "{b,n} <- <<branch,notes>>]",null);
   
   Transformation.createIdentTransformation(cash,notes,null,null);
   Transformation.createIdentTransformation(cash,coins,null,null);

  }
}
