/* 
 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#include "tut_stdafx.h"

#ifndef _WIN32
#include <sstream>
#endif

#include "grt_test_utility.h"
#include "testgrt.h"
#include "grtsqlparser/sql_facade.h"
#include "wb_helpers.h"

BEGIN_TEST_DATA_CLASS(mysql_sql_parser)
public:
  WBTester wbt;
  SqlFacade::Ref sql_facade;
  db_mgmt_RdbmsRef rdbms;
  DictRef options;
  void test_import_sql(int test_no, const char *old_schema_name= NULL, const char *new_schema_name= NULL);
END_TEST_DATA_CLASS


TEST_MODULE(mysql_sql_parser, "SQL Parser (MySQL)");


TEST_FUNCTION(1)
{
  wbt.create_new_document();
  GRT *grt= wbt.grt;

  ensure_equals("loaded physycal model count", wbt.wb->get_document()->physicalModels().count(), 1U);

  options= DictRef(grt);
  options.set("gen_fk_names_when_empty", IntegerRef(0));

  rdbms= wbt.wb->get_document()->physicalModels().get(0)->rdbms();

  sql_facade= SqlFacade::instance_for_rdbms(rdbms);
  ensure("failed to get sqlparser module", (NULL != sql_facade));
}


void Test_object_base<mysql_sql_parser>::test_import_sql(int test_no, const char *old_schema_name, const char *new_schema_name)
{
  static const char* TEST_DATA_DIR= "data/modules_grt/wb_mysql_import/sql/";

  /* set filenames & messages based on test no. */
  std::ostringstream oss;
  oss << test_no;
  std::string test_message=                "SQL (" + oss.str() + ")";
  std::string test_sql_filename=           TEST_DATA_DIR + oss.str() + ".sql";
  std::string test_catalog_state_filename= TEST_DATA_DIR + oss.str() + ".xml";
  std::string res_catalog_state_filename=  TEST_DATA_DIR + oss.str() + "_res.xml";

  /* use initialized grt */
  GRT* grt= rdbms.get_grt();

  /* create & init new catalog */
  db_mysql_CatalogRef res_catalog(grt);
  res_catalog->version(rdbms->version());
  res_catalog->defaultCharacterSetName("utf8");
  res_catalog->defaultCollationName("utf8_general_ci");
  grt::replace_contents(res_catalog->simpleDatatypes(), rdbms->simpleDatatypes());

  /* parse sql */
  sql_facade->parseSqlScriptFileEx(res_catalog, test_sql_filename, options);

  /* rename schema if asked */
  if (old_schema_name && new_schema_name)
    sql_facade->renameSchemaReferences(res_catalog, old_schema_name, new_schema_name);

  /* serialization */
  grt->serialize(res_catalog, res_catalog_state_filename);

  /* unserialization */
  db_CatalogRef test_catalog= db_mysql_CatalogRef::cast_from(ValueRef(grt->unserialize(test_catalog_state_filename)));

  /* comparison */
  grt_ensure_equals(test_message.c_str(), res_catalog, test_catalog);
}


/* TABLE */
TEST_FUNCTION(2) { test_import_sql(0); }
TEST_FUNCTION(3) { test_import_sql(1); }
TEST_FUNCTION(4) { test_import_sql(2); }
TEST_FUNCTION(5) { test_import_sql(3); }
TEST_FUNCTION(6) { test_import_sql(4); }
TEST_FUNCTION(7) { test_import_sql(5); }
TEST_FUNCTION(8) { test_import_sql(6); }
TEST_FUNCTION(9) { test_import_sql(7); }
TEST_FUNCTION(10) { test_import_sql(8); }
TEST_FUNCTION(11) { test_import_sql(9); }
TEST_FUNCTION(12) { test_import_sql(10); }
TEST_FUNCTION(13) { test_import_sql(11); }
TEST_FUNCTION(14) { test_import_sql(12); }
TEST_FUNCTION(15) { test_import_sql(13); }
TEST_FUNCTION(16) { test_import_sql(14); }
TEST_FUNCTION(17) { test_import_sql(15); }
TEST_FUNCTION(18) { test_import_sql(16); }
TEST_FUNCTION(19) { test_import_sql(17); }
TEST_FUNCTION(20) { test_import_sql(18); }


/* INDEX */
TEST_FUNCTION(30) { test_import_sql(50); }
TEST_FUNCTION(31) { test_import_sql(51); }


/* VIEW */
TEST_FUNCTION(35) { test_import_sql(100); }
TEST_FUNCTION(36) { test_import_sql(101); }


/* ROUTINE */
TEST_FUNCTION(40) { test_import_sql(150); }
TEST_FUNCTION(41) { test_import_sql(151); }


/* TRIGGER */
TEST_FUNCTION(45) { test_import_sql(200); }


/* EVENT */
//!TEST_FUNCTION(50) { test_import_sql(250); }
//!TEST_FUNCTION(51) { test_import_sql(251); }
//!TEST_FUNCTION(52) { test_import_sql(252); }
//!TEST_FUNCTION(53) { test_import_sql(253); }


/* LOGFILE GROUP, TABLESPACE */
TEST_FUNCTION(55) { test_import_sql(300); }


/* SERVER LINK */
TEST_FUNCTION(60) { test_import_sql(350); }


/* ALTER STATEMENTS */
TEST_FUNCTION(61) { test_import_sql(400); }


/* DROP STATEMENTS */
TEST_FUNCTION(62) { test_import_sql(450); }


/* MISC */
TEST_FUNCTION(65) { test_import_sql(600); } // reusage of stub tables & columns


/* REAL-WORLD SCHEMATA (MANY OBJECTS) */
TEST_FUNCTION(70) { test_import_sql(700); } // sakila-db: schema structures (except of triggers)
TEST_FUNCTION(71) { test_import_sql(701); } // sakila-db: inserts & triggers
TEST_FUNCTION(72) { test_import_sql(702); } // sakila-db: mysqldump file


/* SCHEMA RENAME */
TEST_FUNCTION(80) { test_import_sql(900, "test", "new_schema_name"); }


END_TESTS
