###############################################################################
#
# tkt-e30b820248.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require Eagle.Library
package require Eagle.Test

runTestPrologue

###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

set memory_used [reportSQLiteResources $test_channel true]

###############################################################################

runTest {test tkt-e30b820248-1.1 {disposal ordering} -setup {
  set fileName tkt-e30b820248-1.1.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]
  set name [file rootname [file tail $fileName]]

  set sql { \
    CREATE TABLE t1 (id1 INTEGER); \
    INSERT INTO t1 (id1) VALUES (1); \
    INSERT INTO t1 (id1) VALUES (2); \
    INSERT INTO t1 (id1) VALUES (?); \
    INSERT INTO t1 (id1) VALUES (?); \
    INSERT INTO t1 (id1) VALUES (?); \
    SELECT id1 FROM t1 ORDER BY id1; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data.SQLite;
    using System.Diagnostics;
    using System.IO;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static void Main()
        {
          using (TraceListener listener = new TextWriterTraceListener(
              new FileStream("${test_log}", FileMode.Append,
                  FileAccess.Write, FileShare.ReadWrite), "${name}"))
          {
            Trace.Listeners.Add(listener);
            Trace.WriteLine("---- START TRACE \\"${name}\\"");

            using (SQLiteConnection connection = new SQLiteConnection(
                "Data Source=${dataSource};"))
            {
              connection.Open();
              connection.LogMessage(0, "Connection opened.");

              using (SQLiteTransaction transaction =
                  connection.BeginTransaction())
              {
                connection.LogMessage(0, "Transaction started.");

                using (SQLiteCommand command = connection.CreateCommand())
                {
                  command.Transaction = transaction;
                  command.CommandText = "${sql}";

                  command.Parameters.AddWithValue("x", 3);
                  command.Parameters.AddWithValue("y", 4);
                  command.Parameters.AddWithValue("z", 5);

                  command.ExecuteNonQuery();
                  connection.LogMessage(0, "Command executed.");
                }

                transaction.Commit();
                connection.LogMessage(0, "Transaction committed.");
              }
            }

            Trace.WriteLine("---- END TRACE \\"${name}\\"");
            Trace.Listeners.Remove(listener);
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result \
      [reportSQLiteResources $test_channel true]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql name dataSource id fileName
} -constraints {eagle logFile monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result [appendArgs "^Ok\
System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{\\} " $memory_used \$]}

###############################################################################

for {set i 2} {$i < 5} {incr i} {
  set memory_used [reportSQLiteResources $test_channel true]

  #############################################################################

  runTest {test [appendArgs tkt-e30b820248-1. $i] {disposal ordering} -setup {
    set fileName [appendArgs tkt-e30b820248-1. $i .db]
  } -body {
    set id [object invoke Interpreter.GetActive NextId]
    set dataSource [file join [getDatabaseDirectory] $fileName]
    set name [file rootname [file tail $fileName]]

    set sql { \
      CREATE TABLE t1 (id1 INTEGER); \
      INSERT INTO t1 (id1) VALUES (1); \
      INSERT INTO t1 (id1) VALUES (2); \
      INSERT INTO t1 (id1) VALUES (3); \
      INSERT INTO t1 (id1) VALUES (4); \
      INSERT INTO t1 (id1) VALUES (5); \
      SELECT id1 FROM t1 ORDER BY id1; \
    }

    unset -nocomplain results errors

    set code [compileCSharpWith [subst {
      using System;
      using System.Data.SQLite;
      using System.Diagnostics;
      using System.IO;

      namespace _Dynamic${id}
      {
        public static class Test${id}
        {
          #region Private Static Data
          private static SQLiteConnection connection;
          #endregion

          /////////////////////////////////////////////////////////////////////

          #region Public Static Methods
          public static void OpenConnection()
          {
            connection = new SQLiteConnection("Data Source=${dataSource};");
            connection.Open();
            connection.LogMessage(0, "Connection opened.");
          }

          /////////////////////////////////////////////////////////////////////

          public static SQLiteCommand CreateCommand(
            string sql
            )
          {
            SQLiteCommand command = connection.CreateCommand();
            command.CommandText = sql;
            connection.LogMessage(0, "Command created.");
            return command;
          }

          /////////////////////////////////////////////////////////////////////

          public static SQLiteDataReader ExecuteReader(
            SQLiteCommand command
            )
          {
            SQLiteDataReader dataReader = command.ExecuteReader();
            connection.LogMessage(0, "Command executed.");
            return dataReader;
          }

          /////////////////////////////////////////////////////////////////////

          public static SQLiteDataReader ExecuteReader(
            string sql
            )
          {
            SQLiteCommand command = CreateCommand(sql);
            SQLiteDataReader dataReader = command.ExecuteReader();
            connection.LogMessage(0, "Command executed.");
            return dataReader;
          }

          /////////////////////////////////////////////////////////////////////

          public static void CloseConnection()
          {
            connection.LogMessage(0, "Closing connection...");
            connection.Close();
          }
          #endregion

          /////////////////////////////////////////////////////////////////////

          public static void Main()
          {
            using (TraceListener listener = new TextWriterTraceListener(
                new FileStream("${test_log}", FileMode.Append,
                    FileAccess.Write, FileShare.ReadWrite), "${name}"))
            {
              Trace.Listeners.Add(listener);
              Trace.WriteLine("---- START TRACE \\"${name}\\"");

              OpenConnection();
              SQLiteDataReader dataReader = ExecuteReader("${sql}");

              [expr {$i <= 2 ? {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
              } : ""}]

              dataReader.Close();

              [expr {$i <= 3 ? {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
              } : ""}]

              CloseConnection();

              [expr {$i <= 4 ? {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
              } : ""}]

              Trace.WriteLine("---- END TRACE \\"${name}\\"");
              Trace.Listeners.Remove(listener);
            }
          }
        }
      }
    }] true true true results errors System.Data.SQLite.dll]

    list $code $results \
        [expr {[info exists errors] ? $errors : ""}] \
        [expr {$code eq "Ok" ? [catch {
          object invoke _Dynamic${id}.Test${id} Main
        } result] : [set result ""]}] $result \
        [reportSQLiteResources $test_channel true]
  } -cleanup {
    cleanupDb $fileName

    unset -nocomplain result code results errors sql name dataSource id \
        fileName
  } -constraints {eagle logFile monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite compileCSharp} -match regexp -result [appendArgs "^Ok\
System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{\\} " $memory_used \$]}
}

###############################################################################

unset -nocomplain i

###############################################################################

unset -nocomplain memory_used

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
