//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
using System;
using System.DirectoryServices;
using System.Data;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Configuration;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
namespace SetupAction
{
///
/// This is a custom setup action that overrides Installer base and is called after setup copies filed, automatically
/// by the setup program. It will create IIS virtual directories based on WMI, register script maps, and create the databases.
///
public partial class SetupAction
{
private string SQL_CONN = null;
public static readonly string CONNSTRING_SQLAUTH = "server={0};Database={1};user id={2};password={3};Pooling=false;";
public static readonly string CONNSTRING_WINAUTH = @"server={0};Database={1};Integrated Security=SSPI;";
//newstrings
string CREATE_LOADACCOUNTPROFILEXML = @"setup_utilities\DATALOAD\CreateInsertXMLAccountProfileProc.sql";
string CREATE_LOADACCOUNTXML = @"setup_utilities\DATALOAD\CreateInsertXMLAccountProc.sql";
string CREATE_LOADHOLDINGXML = @"setup_utilities\DATALOAD\CreateInsertXMLHoldingProc.sql";
string CREATE_LOADORDERSXML = @"setup_utilities\DATALOAD\CreateInsertXMLOrdersProc.sql";
string CREATE_LOADQUOTEXML = @"setup_utilities\DATALOAD\CreateInsertXMLQuoteProc.sql";
string MSG_CHECK_SQL_AUTH = string.Empty;
public static string dbServer = null;
private string installPath = null;
//private string createDBs = null;
public string dbAdmin = null;
public string dbPassword = null;
public string authType = null;
public static readonly string tradeuser = "trade";
public static readonly string tradepassword = "yyy";
public static readonly string TRADEDB = "StockTraderDB";
public const string TRADEDB_CREATE_FILE = "createdb.sql";
string GetConnectionString(string databaseName)
{
if (authType != null && authType.Equals("Integrated", StringComparison.InvariantCultureIgnoreCase))
return string.Format(CONNSTRING_WINAUTH, new object[] { dbServer, databaseName });
return string.Format(CONNSTRING_SQLAUTH, new object[] { dbServer, databaseName, dbAdmin, dbPassword });
}
//public void Install(System.Collections.IDictionary stateSaver)
public void Install()
{
//Get values from config
dbServer = ConfigurationManager.AppSettings.Get("dbServer");
installPath = ConfigurationManager.AppSettings.Get("installPath");
//not used createDBs = ConfigurationManager.AppSettings.Get("createDBs");
dbAdmin = ConfigurationManager.AppSettings.Get("dbAdmin");
dbPassword = ConfigurationManager.AppSettings.Get("dbPassword");
authType = ConfigurationManager.AppSettings.Get("authType");
//string CREATE_LOADACCOUNTPROFILEXML = @"setup_utilities\DATALOAD\" + createfilename;
//string CREATE_LOADACCOUNTXML = string.Empty;
//string CREATE_LOADHOLDINGXML = string.Empty;
//string CREATE_LOADORDERSXML = string.Empty;
//string CREATE_LOADQUOTEXML = string.Empty;
try
{
createDatabase(installPath, TRADEDB_CREATE_FILE, TRADEDB, tradeuser, tradepassword);
createLoadXmlStockTraderDBProcs(installPath, TRADEDB);
loadStockTraderDB(installPath, TRADEDB);
}
catch (Exception e)
{
throw new Exception("MSG_DBFAIL " + e.Message);
}
}
///
/// Similar to createLoadXmlRepositoryProcs, except for StockTraderDB tables.
///
///
///
public void createLoadXmlStockTraderDBProcs(string installPath, string databaseName)
{
SQL_CONN = GetConnectionString(databaseName);
SqlConnection sqlConnection = new SqlConnection(SQL_CONN);
sqlConnection.Open();
///ACCOUNT_PROFILE_LOAD_XML
System.IO.StreamReader file = new System.IO.StreamReader(installPath + CREATE_LOADACCOUNTPROFILEXML);
string createCommand = file.ReadToEnd();
file.Close();
SqlCommand sqlCommand = new SqlCommand(createCommand, sqlConnection);
sqlCommand.CommandType = CommandType.Text;
sqlCommand.ExecuteNonQuery();
Console.Write(".");
///ACCOUNT_LOAD_XML
file = new System.IO.StreamReader(installPath + CREATE_LOADACCOUNTXML);
createCommand = file.ReadToEnd();
file.Close();
sqlCommand = new SqlCommand(createCommand, sqlConnection);
sqlCommand.CommandType = CommandType.Text;
sqlCommand.ExecuteNonQuery();
Console.Write(".");
///HOLDING_LOAD_XML
file = new System.IO.StreamReader(installPath + CREATE_LOADHOLDINGXML);
createCommand = file.ReadToEnd();
file.Close();
sqlCommand = new SqlCommand(createCommand, sqlConnection);
sqlCommand.CommandType = CommandType.Text;
sqlCommand.ExecuteNonQuery();
Console.Write(".");
///ORDERS_LOAD_XML
file = new System.IO.StreamReader(installPath + CREATE_LOADORDERSXML);
createCommand = file.ReadToEnd();
file.Close();
sqlCommand = new SqlCommand(createCommand, sqlConnection);
sqlCommand.CommandType = CommandType.Text;
sqlCommand.ExecuteNonQuery();
Console.Write(".");
///QUOTE_LOAD_XML
file = new System.IO.StreamReader(installPath + CREATE_LOADQUOTEXML);
createCommand = file.ReadToEnd();
file.Close();
sqlCommand = new SqlCommand(createCommand, sqlConnection);
sqlCommand.CommandType = CommandType.Text;
sqlCommand.ExecuteNonQuery();
Console.Write(".");
sqlConnection.Close();
}
///
/// Creates the initial DB schemas for all StockTrader databases.
///
///
///
///
///
///
public void createDatabase(string installPath, string createfilename, string repositoryName, string userid, string password)
{
string configDB = "IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) EXEC [" + repositoryName + "].[dbo].[sp_fulltext_database] @action = 'enable';" +
"ALTER DATABASE [" + repositoryName + "] SET ANSI_NULL_DEFAULT OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET ANSI_NULLS OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET ANSI_PADDING OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET ANSI_WARNINGS OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET ARITHABORT OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET AUTO_CLOSE OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET AUTO_CREATE_STATISTICS ON;" +
"ALTER DATABASE [" + repositoryName + "] SET AUTO_SHRINK OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET AUTO_UPDATE_STATISTICS ON;" +
"ALTER DATABASE [" + repositoryName + "] SET CURSOR_CLOSE_ON_COMMIT OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET CURSOR_DEFAULT GLOBAL;" +
"ALTER DATABASE [" + repositoryName + "] SET CONCAT_NULL_YIELDS_NULL OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET NUMERIC_ROUNDABORT OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET QUOTED_IDENTIFIER OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET RECURSIVE_TRIGGERS OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET ENABLE_BROKER;" +
"ALTER DATABASE [" + repositoryName + "] SET AUTO_UPDATE_STATISTICS_ASYNC OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET DATE_CORRELATION_OPTIMIZATION OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET TRUSTWORTHY OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET ALLOW_SNAPSHOT_ISOLATION OFF;" +
"ALTER DATABASE [" + repositoryName + "] SET PARAMETERIZATION SIMPLE;" +
"ALTER DATABASE [" + repositoryName + "] SET READ_WRITE;" +
"ALTER DATABASE [" + repositoryName + "] SET RECOVERY FULL;" +
"ALTER DATABASE [" + repositoryName + "] SET MULTI_USER;" +
"ALTER DATABASE [" + repositoryName + "] SET PAGE_VERIFY CHECKSUM;" +
"ALTER DATABASE [" + repositoryName + "] SET DB_CHAINING OFF;";
string dropDB = null;
SQL_CONN = GetConnectionString("master");
SqlConnection sqlConnection = new SqlConnection(SQL_CONN);
try
{
sqlConnection.Open();
dropDB = "IF EXISTS (SELECT name FROM sys.databases WHERE name = N'" + repositoryName + "') DROP DATABASE [" + repositoryName + "]";
SqlCommand sqlCommand = new SqlCommand(dropDB, sqlConnection);
sqlCommand.CommandTimeout = 1200;
sqlCommand.CommandType = CommandType.Text;
//Drop DB
sqlCommand.ExecuteNonQuery();
//Create DB
string strCreateDB = "CREATE DATABASE [" + repositoryName + "];";
sqlCommand.CommandText = strCreateDB;
sqlCommand.ExecuteNonQuery();
Console.Write(".");
//Config DB
sqlCommand.CommandText = configDB;
sqlCommand.ExecuteNonQuery();
Console.Write(".");
string createlogin = "IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE name = N'" + userid + "') " +
"CREATE LOGIN [" + userid + "] WITH PASSWORD='" + password + "', DEFAULT_DATABASE=" +
"[" + repositoryName + "], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF;";
string createuser = "IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N'" + userid + "') CREATE USER" +
"[" + userid + "] FOR LOGIN [" + userid + "] WITH DEFAULT_SCHEMA=[dbo];";
//create login
sqlCommand.CommandText = createlogin;
sqlCommand.ExecuteNonQuery();
Console.Write(".");
//Logout of Master
sqlConnection.Close();
//Now create user for new DB by logging in to new DB with admin rights
SQL_CONN = GetConnectionString(repositoryName);
sqlConnection = new SqlConnection(SQL_CONN);
Server server = new Server(new ServerConnection(sqlConnection));
server.ConnectionContext.ExecuteNonQuery(createuser);
Console.Write(".");
//Logout of Trade DB
sqlConnection.Close();
System.Data.SqlClient.SqlConnection.ClearAllPools();
//Login to Master and use SMO to create role mapping of DBO
sqlConnection = new SqlConnection(SQL_CONN);
//new SMO functionality
server = new Server(new ServerConnection(sqlConnection));
server.ConnectionContext.ExecuteNonQuery("exec sp_addrolemember 'db_owner','" + userid + "'");
Console.Write(".");
//Logout
sqlConnection.Close();
//Login as newly created user. Don't need to but rather test connectivity here right away to make sure DB in good state for new trade user.
SQL_CONN = GetConnectionString(repositoryName);
sqlConnection = new SqlConnection(SQL_CONN);
try
{
sqlConnection.Open();
}
catch (Exception e)
{
throw new Exception(MSG_CHECK_SQL_AUTH + ". Exc: " + e.Message);
}
///Create Schema for DB
System.IO.StreamReader file = new System.IO.StreamReader(installPath + @"setup_utilities\DATALOAD\" + createfilename);
string createCommand = file.ReadToEnd();
file.Close();
sqlCommand = new SqlCommand(createCommand, sqlConnection);
sqlCommand.CommandType = CommandType.Text;
sqlCommand.ExecuteNonQuery();
Console.Write(".");
sqlConnection.Close();
return;
}
catch (Exception e)
{
if (sqlConnection.State == ConnectionState.Open)
sqlConnection.Close();
System.Data.SqlClient.SqlConnection.ClearAllPools();
sqlConnection.Dispose();
throw new Exception(e.Message);
}
}
///
/// Loads the StockTraderDB tables with initial data from XML files.
///
///
///
public void loadStockTraderDB(string installPath, string repository)
{
SQL_CONN = GetConnectionString(repository);
string xmlFile = null;
string sql = null;
string table = null;
for (int i = 0; i < 5; i++)
{
switch (i)
{
case 0:
{
xmlFile = installPath + "setup_utilities\\DATALOAD\\" + repository + "\\Account.xml";
sql = "InsertAccountFromXML";
table = "dbo.ACCOUNT";
break;
}
case 1:
{
xmlFile = installPath + "setup_utilities\\DATALOAD\\" + repository + "\\AccountProfile.xml";
sql = "InsertAccountProfileFromXML";
table = null;
break;
}
case 2:
{
xmlFile = installPath + "setup_utilities\\DATALOAD\\" + repository + "\\Quote.xml";
sql = "InsertQuoteFromXML";
table = null;
break;
}
case 3:
{
xmlFile = installPath + "setup_utilities\\DATALOAD\\" + repository + "\\Holding.xml";
sql = "InsertHoldingFromXML";
table = "dbo.HOLDING";
break;
}
case 4:
{
xmlFile = installPath + "setup_utilities\\DATALOAD\\" + repository + "\\Orders.xml";
sql = "InsertOrdersFromXML";
table = "dbo.ORDERS";
break;
}
}
SqlConnection conn = new SqlConnection(SQL_CONN);
conn.Open();
string configContent = null;
if (table != null)
{
//Need to turn off identities first for certain tables.
SqlCommand cmd = new SqlCommand("SET IDENTITY_INSERT " + table + " ON");
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
Console.Write(".");
}
using (StreamReader sr = new StreamReader(xmlFile))
{
configContent = sr.ReadToEnd();
}
SqlParameter parmDoc = new SqlParameter("sXML", SqlDbType.NText, 60000000);
parmDoc.Value = configContent;
SqlCommand cmd2 = new SqlCommand(sql);
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.Connection = conn;
cmd2.Parameters.Add(parmDoc);
try
{
cmd2.ExecuteNonQuery();
Console.Write(".");
}
catch (Exception e)
{
throw new Exception(e.Message);
}
if (table != null)
{
cmd2 = new SqlCommand("SET IDENTITY_INSERT " + table + " OFF");
cmd2.Connection = conn;
cmd2.CommandType = CommandType.Text;
cmd2.ExecuteNonQuery();
Console.Write(".");
}
conn.Close();
}
}
}
}