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

package require Eagle
package require EagleLibrary
package require EagleTest

runTestPrologue

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

package require System.Data.SQLite.Test
runSQLiteTestPrologue

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

#
# NOTE: Setup the variables that refer to the various files required by the
#       tests in this file.
#
set testExeFile [getBuildFileName test.exe]
set testLinqExeFile [getBuildFileName testlinq.exe]
set testLinqOutFile [file nativename [file join $path testlinq.out]]
set northwindEfDbFile [file nativename [file join [file dirname $path] \
    testlinq northwindEF.db]]

#
# NOTE: Setup the test constraints specific to the tests in this file.
#
if {![haveConstraint file_[file tail $testExeFile]]} then {
  checkForFile $test_channel $testExeFile
}

if {![haveConstraint file_[file tail $testLinqExeFile]]} then {
  checkForFile $test_channel $testLinqExeFile
}

if {![haveConstraint file_[file tail $northwindEfDbFile]]} then {
  checkForFile $test_channel $northwindEfDbFile
}

if {![haveConstraint file_[file tail $testLinqOutFile]]} then {
  checkForFile $test_channel $testLinqOutFile
}

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

runTest {test basic-1.1 {unit tests from the 'test' project} -setup {
  catch {file delete [file join [file dirname $testExeFile] Test.db3]}
} -body {
  set output ""

  set code [catch {
    testClrExec $testExeFile [list -eventflags Wait -directory \
    [file dirname $testExeFile] -stdout output -success 0] -autoRun
  } error]

  tlog "---- BEGIN STDOUT OUTPUT\n"
  tlog $output
  tlog "\n---- END STDOUT OUTPUT\n"

  list $code [expr {$code == 0 ? "" : $error}]
} -cleanup {
  unset -nocomplain code output error
} -constraints {eagle file_test.exe} -result {0 {}}}

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

runTest {test basic-1.2 {unit tests from the 'testlinq' project} -setup {
  #
  # NOTE: Re-copy the reference database file used for this unit test to the
  #       build directory in case it has been changed by a previous test run.
  #
  file copy -force $northwindEfDbFile \
      [file join [getBuildDirectory] [file tail $northwindEfDbFile]]

  #
  # NOTE: We need to make 100% sure that the console output encoding is the
  #       same as when the 'testlinq.out' file was created.
  #
  set savedEncoding [object invoke Console OutputEncoding]
  set encoding [object invoke System.Text.Encoding GetEncoding Windows-1252]

  object invoke Console OutputEncoding $encoding
} -body {
  set output ""

  set code [catch {
    testClrExec $testLinqExeFile [list -eventflags Wait -directory \
    [file dirname $testLinqExeFile] -stdout output -success 0]
  } error]

  tlog "---- BEGIN STDOUT OUTPUT\n"
  tlog $output
  tlog "\n---- END STDOUT OUTPUT\n"

  list $code [string equal $output [readFile $testLinqOutFile]] \
      [expr {$code == 0 ? "" : $error}]
} -cleanup {
  catch {object invoke Console OutputEncoding $savedEncoding}

  unset -nocomplain code output error savedEncoding encoding
} -constraints \
{eagle monoToDo file_testlinq.exe file_northwindEF.db file_testlinq.out} \
-result {0 True {}}}

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

runTest {test basic-1.3 {SELECT scalar/reader, CREATE, INSERT} -setup {
  setupDb [set fileName basic-1.3.db]
} -body {
  set result [list]

  lappend result [sql execute -execute scalar $db \
      "SELECT sqlite_source_id();"]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y, z);"
  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(1, 'foo', 1234);"

  sql execute -execute reader $db "SELECT x, y, z FROM t1;"

  foreach name [lsort [array names rows]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^\{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [0-9a-f]{40}\}\
\{1 \{\{x 1\} \{y foo\} \{z 1234\}\}\} \{count 1\} \{names \{x y z\}\}$}}

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

runTest {test basic-1.4 {GetSchema with ReservedWords} -setup {
  setupDb [set fileName basic-1.4.db]
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getTemporaryPath] basic-1.4.db]

  unset -nocomplain results errors

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

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static DataTable GetReservedWords()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            return connection.GetSchema("ReservedWords");
          }
        }

        public static void Main()
        {
          // do nothing.
        }
      }
    }
  }] 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} GetReservedWords
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName
  unset -nocomplain result results errors code dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
System#Data#DataTable#\d+$}}

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

runTest {test basic-1.5 {GetSchema with ForeignKeys} -setup {
  setupDb [set fileName basic-1.5.db]
} -body {
  sql execute $db {
    CREATE TABLE t1(
      x INTEGER REFERENCES t2 MATCH FULL
      ON UPDATE SET DEFAULT ON DELETE CASCADE
      DEFAULT 1
    );
  }

  sql execute $db "CREATE TABLE t2(x INTEGER REFERENCES t3);"

  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getTemporaryPath] basic-1.5.db]

  unset -nocomplain results errors

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

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static DataRowCollection GetForeignKeys()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            return connection.GetSchema("ForeignKeys").Rows;
          }
        }

        public static void Main()
        {
          // do nothing.
        }
      }
    }
  }] results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        set rows [list]
        set foreignKeys [object invoke _Dynamic${id}.Test${id} GetForeignKeys]

        object foreach -alias foreignKey $foreignKeys {
          lappend rows [list \
              [$foreignKey Item CONSTRAINT_CATALOG] \
              [$foreignKey Item CONSTRAINT_NAME] \
              [$foreignKey Item TABLE_CATALOG] \
              [$foreignKey Item TABLE_NAME] \
              [$foreignKey Item CONSTRAINT_TYPE] \
              [$foreignKey Item IS_DEFERRABLE] \
              [$foreignKey Item INITIALLY_DEFERRED] \
              [$foreignKey Item FKEY_FROM_COLUMN] \
              [$foreignKey Item FKEY_TO_CATALOG] \
              [$foreignKey Item FKEY_TO_TABLE] \
              [$foreignKey Item FKEY_TO_COLUMN] \
              [$foreignKey Item FKEY_FROM_ORDINAL_POSITION] \
              [$foreignKey Item FKEY_ON_UPDATE] \
              [$foreignKey Item FKEY_ON_DELETE] \
              [$foreignKey Item FKEY_MATCH]]
        }

        set rows
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result rows foreignKey foreignKeys results errors code \
      dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
\{\{main FK_t1_0 main t1 \{FOREIGN KEY\} False False x main t2 \{\} 0 \{SET\
DEFAULT\} CASCADE NONE\} \{main FK_t2_0 main t2 \{FOREIGN KEY\} False False x\
main t3 \{\} 0 \{NO ACTION\} \{NO ACTION\} NONE\}\}$}}

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

runTest {test basic-1.6 {SQLITE_FCNTL_WIN32_AV_RETRY} -setup {
  setupDb [set fileName basic-1.6.db]
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getTemporaryPath] basic-1.6.db]

  unset -nocomplain results errors

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

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static bool TestSetAvRetry(
          ref int count,
          ref int interval
          )
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            //
            // NOTE: Set the requested retry parameter values.
            //
            if (connection.SetAvRetry(ref count, ref interval) != 0)
              return false;

            //
            // NOTE: Query the retry parameter values.
            //
            int newCount = -1; int newInterval = -1;

            if (connection.SetAvRetry(ref newCount, ref newInterval) != 0)
              return false;

            //
            // NOTE: Make sure the retry parameter values were set.
            //
            return (newCount == count && newInterval == interval);
          }
        }

        public static void Main()
        {
          // do nothing.
        }
      }
    }
  }] results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        set savedCount -1; set savedInterval -1

        object invoke _Dynamic${id}.Test${id} TestSetAvRetry \
            savedCount savedInterval

        set count 5; set interval 50

        object invoke _Dynamic${id}.Test${id} TestSetAvRetry \
            count interval
      } result] : [set result ""]}] $result
} -cleanup {
  if {[info exists savedCount]} then {
    #
    # NOTE: Restore the saved retry count, if possible.
    #
    catch {
      set interval -1
      object invoke _Dynamic${id}.Test${id} TestSetAvRetry savedCount interval
    }
  }

  if {[info exists savedInterval]} then {
    #
    # NOTE: Restore the saved retry interval, if possible.
    #
    catch {
      set count -1
      object invoke _Dynamic${id}.Test${id} TestSetAvRetry count savedInterval
    }
  }

  cleanupDb $fileName

  unset -nocomplain result count interval savedCount savedInterval results \
      errors code dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
True$}}

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

runTest {test basic-1.7 {properly closed database file (non-query)} -setup {
  set fileName basic-1.7.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getTemporaryPath] $fileName]

  set sql { \
    BEGIN EXCLUSIVE TRANSACTION; \
    CREATE TABLE t1(x INTEGER); \
    INSERT INTO t1 (x) VALUES(1); \
    SELECT * FROM t1; \
  }

  unset -nocomplain results errors

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

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = new SQLiteCommand("${sql}",
                connection))
            {
              command.ExecuteNonQuery();
            }
          }
        }
      }
    }
  }] 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 \
      [close [open $dataSource RDONLY 0 "" -share None]]
} -cleanup {
  cleanupDb $fileName

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

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

runTest {test basic-1.8 {properly closed database file (reader #1)} -setup {
  set fileName basic-1.8.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getTemporaryPath] $fileName]

  set sql { \
    BEGIN EXCLUSIVE TRANSACTION; \
    CREATE TABLE t1(x INTEGER); \
    INSERT INTO t1 (x) VALUES(1); \
    SELECT * FROM t1; \
  }

  unset -nocomplain results errors

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

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = new SQLiteCommand("${sql}",
                connection))
            {
              using (SQLiteDataReader dataReader = command.ExecuteReader())
              {
                // do nothing.
              }
            }
          }
        }
      }
    }
  }] 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 \
      [close [open $dataSource RDONLY 0 "" -share None]]
} -cleanup {
  cleanupDb $fileName

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

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

runTest {test basic-1.9 {properly closed database file (reader #2)} -setup {
  set fileName basic-1.9.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getTemporaryPath] $fileName]

  set sql { \
    BEGIN EXCLUSIVE TRANSACTION; \
    CREATE TABLE t1(x INTEGER); \
    INSERT INTO t1 (x) VALUES(1); \
    SELECT * FROM t1; \
  }

  unset -nocomplain results errors

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

    namespace _Dynamic${id}
    {
      public class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = new SQLiteCommand("${sql}",
                connection))
            {
              using (SQLiteDataReader dataReader = command.ExecuteReader(
                  CommandBehavior.CloseConnection))
              {
                // do nothing.
              }
            }
          }
        }
      }
    }
  }] 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 \
      [close [open $dataSource RDONLY 0 "" -share None]]
} -cleanup {
  cleanupDb $fileName

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

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

runTest {test basic-1.10 {Changes property} -setup {
  setupDb [set fileName basic-1.10.db]
} -body {
  set connection [object invoke -flags +NonPublic -objectflags +NoDispose \
      Interpreter.GetActive.connections Item $db]

  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y, z);"

  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(1, 'foo', 1234);"
  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(2, 'bar', 5678);"
  lappend result [object invoke $connection Changes]

  sql execute $db "UPDATE t1 SET y = 'foobar';"
  lappend result [object invoke $connection Changes]

  sql execute -execute reader $db "SELECT x, y, z FROM t1;"
  lappend result [object invoke $connection Changes]

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result connection db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result {1 2 2 {1 {{x 1} {y foobar} {z 1234}}} {2 {{x 2} {y foobar} {z 5678}}}}}

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

runTest {test basic-1.11 {LastInsertRowId property} -setup {
  setupDb [set fileName basic-1.11.db]
} -body {
  set connection [object invoke -flags +NonPublic -objectflags +NoDispose \
      Interpreter.GetActive.connections Item $db]

  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y, z);"

  sql execute $db "CREATE TABLE t2(x INTEGER PRIMARY KEY AUTOINCREMENT, y, z);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(1, 'foo', 1234);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "INSERT INTO t1 (x, y, z) VALUES(2, 'bar', 5678);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "UPDATE t1 SET y = 'foobar';"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "INSERT INTO t2 (y, z) VALUES('foo', 1234);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "INSERT INTO t2 (y, z) VALUES('bar', 5678);"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute $db "UPDATE t2 SET y = 'foobar';"
  lappend result [object invoke $connection LastInsertRowId]

  sql execute -execute reader $db "SELECT x, y, z FROM t1;"
  lappend result [object invoke $connection LastInsertRowId]

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  sql execute -execute reader $db "SELECT x, y, z FROM t2;"
  lappend result [object invoke $connection LastInsertRowId]

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result connection db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result {0 1 2 2 1 2 2 2 {1 {{x 1} {y foobar} {z 1234}}} {2 {{x 2} {y foobar}\
{z 5678}}} 2 {1 {{x 1} {y foobar} {z 1234}}} {2 {{x 2} {y foobar} {z 5678}}}}}

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

runTest {test basic-1.12 {DateTime using Unix epoch} -setup {
  setupDb [set fileName basic-1.12.db] "" "" "DateTimeFormat=UnixEpoch;"
} -body {
  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y DATETIME);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(1, 1302825600);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(2, 1334448000);"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(3, 1365984000);"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(4, ?);" \
      [list param1 Int32 1302825600]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(5, ?);" \
      [list param1 Int32 1334448000]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(6, ?);" \
      [list param1 Int32 1365984000]

  sql execute -verbatim $db "INSERT INTO t1 (x, y) VALUES(7, ?);" \
      [list param1 DateTime 1302825600]

  sql execute -verbatim $db "INSERT INTO t1 (x, y) VALUES(8, ?);" \
      [list param1 DateTime 1334448000]

  sql execute -verbatim $db "INSERT INTO t1 (x, y) VALUES(9, ?);" \
      [list param1 DateTime 1365984000]

  sql execute -execute reader -datetimeformat "MM/dd/yyyy HH:mm:ss" $db \
      "SELECT x, y FROM t1 ORDER BY x;"

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result {{1 {{x 1} {y {04/15/2011 00:00:00}}}} {2 {{x 2} {y {04/15/2012\
00:00:00}}}} {3 {{x 3} {y {04/15/2013 00:00:00}}}} {4 {{x 4} {y {04/15/2011\
00:00:00}}}} {5 {{x 5} {y {04/15/2012 00:00:00}}}} {6 {{x 6} {y {04/15/2013\
00:00:00}}}} {7 {{x 7} {y {04/15/2011 00:00:00}}}} {8 {{x 8} {y {04/15/2012\
00:00:00}}}} {9 {{x 9} {y {04/15/2013 00:00:00}}}}}}

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

set date [clock format [clock seconds] -format yyyy-MM-dd]

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

runTest {test basic-1.13 {DateTime using invariant culture} -setup {
  setupDb [set fileName basic-1.13.db] "" "" "DateTimeFormat=InvariantCulture;"
} -body {
  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y DATETIME);"

  sql execute $db \
      "INSERT INTO t1 (x, y) VALUES(1, 'Wednesday, 16 December 2009');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(2, '12:00:00');"

  sql execute $db \
      "INSERT INTO t1 (x, y) VALUES(3, 'Wednesday, 16 December 2009 12:00:00');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(4, '12/16/2009');"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(5, '12:00');"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(6, '12/16/2009 12:00');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(7, ?);" \
      [list param1 DateTime "Wednesday, 16 December 2009"]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(8, ?);" \
      [list param1 DateTime 12:00:00]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(9, ?);" \
      [list param1 DateTime "Wednesday, 16 December 2009 12:00:00"]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(10, ?);" \
      [list param1 DateTime 12/16/2009]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(11, ?);" \
      [list param1 DateTime 12:00]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(12, ?);" \
      [list param1 DateTime "12/16/2009 12:00"]

  sql execute -execute reader -datetimeformat "MM/dd/yyyy HH:mm:ss" $db \
      "SELECT x, CAST(y AS TEXT) AS y2 FROM t1 ORDER BY x;"

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result [subst {{1 {{x 1} {y2 {Wednesday, 16 December 2009}}}} {2 {{x 2} {y2\
12:00:00}}} {3 {{x 3} {y2 {Wednesday, 16 December 2009 12:00:00}}}} {4 {{x 4}\
{y2 12/16/2009}}} {5 {{x 5} {y2 12:00}}} {6 {{x 6} {y2 {12/16/2009 12:00}}}} {7\
{{x 7} {y2 2009-12-16T00:00:00.0000000Z}}} {8 {{x 8} {y2\
${date}T12:00:00.0000000Z}}} {9 {{x 9} {y2 2009-12-16T12:00:00.0000000Z}}}\
{10 {{x 10} {y2 2009-12-16T00:00:00.0000000Z}}} {11 {{x 11} {y2\
${date}T12:00:00.0000000Z}}} {12 {{x 12} {y2 2009-12-16T12:00:00.0000000Z}}}}]}

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

runTest {test basic-1.14 {DateTime using current culture} -setup {
  setupDb [set fileName basic-1.14.db] "" "" "DateTimeFormat=CurrentCulture;"
} -body {
  set result [list]

  sql execute $db "CREATE TABLE t1(x INTEGER PRIMARY KEY ASC, y DATETIME);"

  sql execute $db \
      "INSERT INTO t1 (x, y) VALUES(1, 'Wednesday, 16 December 2009');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(2, '12:00:00');"

  sql execute $db \
      "INSERT INTO t1 (x, y) VALUES(3, 'Wednesday, 16 December 2009 12:00:00');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(4, '12/16/2009');"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(5, '12:00');"
  sql execute $db "INSERT INTO t1 (x, y) VALUES(6, '12/16/2009 12:00');"

  sql execute $db "INSERT INTO t1 (x, y) VALUES(7, ?);" \
      [list param1 DateTime "Wednesday, 16 December 2009"]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(8, ?);" \
      [list param1 DateTime 12:00:00]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(9, ?);" \
      [list param1 DateTime "Wednesday, 16 December 2009 12:00:00"]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(10, ?);" \
      [list param1 DateTime 12/16/2009]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(11, ?);" \
      [list param1 DateTime 12:00]

  sql execute $db "INSERT INTO t1 (x, y) VALUES(12, ?);" \
      [list param1 DateTime "12/16/2009 12:00"]

  sql execute -execute reader -datetimeformat "MM/dd/yyyy HH:mm:ss" $db \
      "SELECT x, CAST(y AS TEXT) AS y2 FROM t1 ORDER BY x;"

  foreach name [lsort -integer [array names rows -regexp {^\d+$}]] {
    lappend result [list $name $rows($name)]
  }

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain name rows result db fileName
} -constraints \
{eagle culture.en_US monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -result [subst {{1 {{x 1} {y2 {Wednesday, 16 December\
2009}}}} {2 {{x 2} {y2 12:00:00}}} {3 {{x 3} {y2 {Wednesday, 16 December 2009\
12:00:00}}}} {4 {{x 4} {y2 12/16/2009}}} {5 {{x 5} {y2 12:00}}} {6 {{x 6} {y2\
{12/16/2009 12:00}}}} {7 {{x 7} {y2 2009-12-16T00:00:00.0000000Z}}} {8 {{x 8}\
{y2 ${date}T12:00:00.0000000Z}}} {9 {{x 9} {y2 2009-12-16T12:00:00.0000000Z}}}\
{10 {{x 10} {y2 2009-12-16T00:00:00.0000000Z}}} {11 {{x 11} {y2\
${date}T12:00:00.0000000Z}}} {12 {{x 12} {y2 2009-12-16T12:00:00.0000000Z}}}}]}

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

unset -nocomplain date

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

unset -nocomplain testExeFile testLinqExeFile northwindEfDbFile testLinqOutFile

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

runSQLiteTestEpilogue
runTestEpilogue
