System.Data.SQLite

Check-in [a5a8b8a682]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Allow finer control over the DateTime parsing and formatting on a per-connection basis. Also, update the Eagle library to the latest trunk.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a5a8b8a68229a42748e2f1de15430e250335f64b
User & Date: mistachkin 2011-09-21 08:27:59.118
Context
2011-09-21
21:46
Add another test for the ExecuteScalar method. check-in: 221fbe52ec user: mistachkin tags: trunk
08:27
Allow finer control over the DateTime parsing and formatting on a per-connection basis. Also, update the Eagle library to the latest trunk. check-in: a5a8b8a682 user: mistachkin tags: trunk
2011-09-20
21:51
Add LastInsertRowId property to the connection class. Also, update docs and tests. check-in: c726454277 user: mistachkin tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to Externals/Eagle/lib/Eagle1.0/init.eagle.
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149

150

151
152
153
154

155
156
157
158
159
160
161
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    eval lappend result $args
  }

  proc getDictionaryValue { dictionary name {default ""} {wrap ""} } {
    #
    # NOTE: Start with the default value.

    #
    set result $default

    #
    # NOTE: Locate the index of the named value we are interested in.
    #
    set index [lsearch -exact $dictionary $name]

    #
    # NOTE: Did we find the name in the row?
    #
    if {$index != -1} then {
      #
      # NOTE: The next element in the list will be the value.
      #
      incr index



      #

      # NOTE: Grab the value.
      #
      set result [appendArgs $wrap [lindex $dictionary $index] $wrap]
    }

  }

  proc getColumnValue { row column {default ""} {wrap ""} } {
    #
    # NOTE: Start with the default value.
    #
    set result $default







|
>

<
|

<
<
<
|
|
|
|
|
|
|
|
<
>
|
>
|
>
|
|
<
<
>







125
126
127
128
129
130
131
132
133
134

135
136



137
138
139
140
141
142
143
144

145
146
147
148
149
150
151


152
153
154
155
156
157
158
159
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    eval lappend result $args
  }

  proc getDictionaryValue { dictionary name {default ""} {wrap ""} } {
    #
    # NOTE: Locate the named value we are interested in.  The dictionary must
    #       be a list with an even number of elements in the following format:
    #

    #       <name1> <value1> <name2> <value2> ... <nameN> <valueN>
    #



    foreach {pairName pairValue} $dictionary {
      #
      # NOTE: Does this name match the one specified by the caller?
      #
      if {$pairName eq $name} then {
        #
        # NOTE: Return the value, optionally wrapped.
        #

        return [appendArgs $wrap $pairValue $wrap]
      }
    }

    #
    # NOTE: Return the default value.
    #


    return $default
  }

  proc getColumnValue { row column {default ""} {wrap ""} } {
    #
    # NOTE: Start with the default value.
    #
    set result $default
Changes to Externals/Eagle/lib/Eagle1.0/test.eagle.
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
          #
          return [tputs $::test_channel [lindex $args 0]]
        }
        2 {
          #
          # NOTE: Either -nonewline or channelId has been specified.
          #
          if {[string equal [lindex $args 0] -nonewline]} then {
            return [tputs $::test_channel [lindex $args end]]
          } else {
            set channel [lindex $args 0]
            set newLine \n
          }
        }
        3 {
          #
          # NOTE: Both -nonewline and channelId are specified, unless
          #       it's an error.  The -nonewline option is supposed to
          #       be argv[0].
          #
          if {[string equal [lindex $args 0] -nonewline]} then {
            set channel [lindex $args 1]
            set newLine ""
          }
        }
      }

      if {[info exists channel]} then {
        if {[string equal $channel stdout]} then {
          #
          # NOTE: Write output for stdout to the test channel.
          #
          return [tputs $::test_channel [appendArgs [lindex $args end] \
              $newLine]]
        }
      }







|












|







|







453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
          #
          return [tputs $::test_channel [lindex $args 0]]
        }
        2 {
          #
          # NOTE: Either -nonewline or channelId has been specified.
          #
          if {[lindex $args 0] eq "-nonewline"} then {
            return [tputs $::test_channel [lindex $args end]]
          } else {
            set channel [lindex $args 0]
            set newLine \n
          }
        }
        3 {
          #
          # NOTE: Both -nonewline and channelId are specified, unless
          #       it's an error.  The -nonewline option is supposed to
          #       be argv[0].
          #
          if {[lindex $args 0] eq "-nonewline"} then {
            set channel [lindex $args 1]
            set newLine ""
          }
        }
      }

      if {[info exists channel]} then {
        if {$channel eq "stdout"} then {
          #
          # NOTE: Write output for stdout to the test channel.
          #
          return [tputs $::test_channel [appendArgs [lindex $args end] \
              $newLine]]
        }
      }
1356
1357
1358
1359
1360
1361
1362
1363











1364












1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
    }

    proc getGarudaDll {} {
      #
      # NOTE: Get the Garuda DLL of the same platform (i.e. machine type)
      #       as the native Tcl shell.
      #
      if {[info exists ::base_path] && \











          [info exists ::eagle_platform(configuration)]} then {












        #
        # NOTE: Build the full path and file name of the Garuda DLL, using
        #       the Eagle base path.  Currently, this will only work
        #       correctly if the test suite is being run from inside the
        #       source tree.
        #
        return [file join $::base_path bin \
            [machineToPlatform [getMachineForTclShell]] [appendArgs \
            $::eagle_platform(configuration) Dll] [appendArgs Garuda \
            [info sharedlibextension]]]
      } else {
        #
        # NOTE: We are missing necessary global variables, return nothing.
        #
        return ""
      }
    }

    proc cleanupExcel {} {
      #







|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>








<
|


|







1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395

1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
    }

    proc getGarudaDll {} {
      #
      # NOTE: Get the Garuda DLL of the same platform (i.e. machine type)
      #       as the native Tcl shell.
      #
      if {[info exists ::base_path]} then {
        #
        # NOTE: If the test configuration is available, use it.  Failing that,
        #       use the build configuration of Eagle itself.
        #
        if {[info exists ::test_configuration]} then {
          #
          # NOTE: Use the test configuration.  The default value is "Release",
          #       as set by the test suite prologue; however, this may have
          #       been overridden.
          #
          set configuration $::test_configuration
        } elseif {[info exists ::eagle_platform(configuration)]} then {
          #
          # NOTE: Use the build configuration of Eagle itself.  This value will
          #       always be "Debug" or "Release".
          #
          set configuration $::eagle_platform(configuration)
        } else {
          #
          # NOTE: We are missing the configuration, return nothing.
          #
          return ""
        }

        #
        # NOTE: Build the full path and file name of the Garuda DLL, using
        #       the Eagle base path.  Currently, this will only work
        #       correctly if the test suite is being run from inside the
        #       source tree.
        #
        return [file join $::base_path bin \
            [machineToPlatform [getMachineForTclShell]] [appendArgs \

            $configuration Dll] [appendArgs Garuda [info sharedlibextension]]]
      } else {
        #
        # NOTE: We are missing the base path, return nothing.
        #
        return ""
      }
    }

    proc cleanupExcel {} {
      #
Changes to Externals/Eagle/lib/Test1.0/constraints.eagle.
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    #
    # NOTE: Is the command available?
    #
    if {[llength [info commands $name]] > 0} then {
      #
      # NOTE: Yes, it appears that it is available.
      #
      addConstraint command.$name

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForFile { channel name {constraint ""} } {
    tputs $channel [appendArgs "---- checking for file \"" $name \
        "\"... "]

    if {[file exists $name]} then {
      #
      # NOTE: Yes, it appears that it is available.
      #
      if {[string length $constraint] > 0} then {
        addConstraint file_$constraint
      } else {
        addConstraint file_[file tail $name]
      }

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForPathFile { channel name {constraint ""} } {
    tputs $channel [appendArgs "---- checking for file \"" $name \
        "\" along PATH... "]

    if {[file exists $name]} then {
      #
      # NOTE: Yes, it appears that it is available [in the exact location they
      #       specified].
      #
      if {[string length $constraint] > 0} then {
        addConstraint file_$constraint
      } else {
        addConstraint file_[file tail $name]
      }

      tputs $channel yes\n

      #
      # NOTE: We are done here, return now.
      #







|
















|

|


















|

|







282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    #
    # NOTE: Is the command available?
    #
    if {[llength [info commands $name]] > 0} then {
      #
      # NOTE: Yes, it appears that it is available.
      #
      addConstraint [appendArgs command. $name]

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForFile { channel name {constraint ""} } {
    tputs $channel [appendArgs "---- checking for file \"" $name \
        "\"... "]

    if {[file exists $name]} then {
      #
      # NOTE: Yes, it appears that it is available.
      #
      if {[string length $constraint] > 0} then {
        addConstraint [appendArgs file_ $constraint]
      } else {
        addConstraint [appendArgs file_ [file tail $name]]
      }

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForPathFile { channel name {constraint ""} } {
    tputs $channel [appendArgs "---- checking for file \"" $name \
        "\" along PATH... "]

    if {[file exists $name]} then {
      #
      # NOTE: Yes, it appears that it is available [in the exact location they
      #       specified].
      #
      if {[string length $constraint] > 0} then {
        addConstraint [appendArgs file_ $constraint]
      } else {
        addConstraint [appendArgs file_ [file tail $name]]
      }

      tputs $channel yes\n

      #
      # NOTE: We are done here, return now.
      #
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
          #       current directory of the PATH being searched.
          #
          if {[file exists [file join $directory $tail]]} then {
            #
            # NOTE: Yes, it appears that it is available in the PATH.
            #
            if {[string length $constraint] > 0} then {
              addConstraint file_$constraint
            } else {
              addConstraint file_[file tail $name]
            }

            tputs $channel yes\n

            #
            # NOTE: We are done here, return now.
            #







|

|







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
          #       current directory of the PATH being searched.
          #
          if {[file exists [file join $directory $tail]]} then {
            #
            # NOTE: Yes, it appears that it is available in the PATH.
            #
            if {[string length $constraint] > 0} then {
              addConstraint [appendArgs file_ $constraint]
            } else {
              addConstraint [appendArgs file_ [file tail $name]]
            }

            tputs $channel yes\n

            #
            # NOTE: We are done here, return now.
            #
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
      #
      # NOTE: Does it look like we are able to contact the network host?
      #
      if {[expr $expr]} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        addConstraint network_$host

        tputs $channel [appendArgs "yes (" $response ")\n"]
      } else {
        tputs $channel no\n
      }
    } else {
      #
      # HACK: Running in Tcl, just assume we have network access.
      #
      addConstraint network_$host

      tputs $channel yes\n
    }
  }

  if {[isEagle]} then {
    ###########################################################################







|









|







612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
      #
      # NOTE: Does it look like we are able to contact the network host?
      #
      if {[expr $expr]} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        addConstraint [appendArgs network_ $host]

        tputs $channel [appendArgs "yes (" $response ")\n"]
      } else {
        tputs $channel no\n
      }
    } else {
      #
      # HACK: Running in Tcl, just assume we have network access.
      #
      addConstraint [appendArgs network_ $host]

      tputs $channel yes\n
    }
  }

  if {[isEagle]} then {
    ###########################################################################
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
        #
        set version [string map [list v "" . ""] $dotVersion]

        #
        # NOTE: Keep track of the specific image runtime version for usage in
        #       test constraints.
        #
        addConstraint imageRuntime$version

        tputs $channel [appendArgs $::eagle_platform(imageRuntimeVersion) \
            " " ( $dotVersion ) \n]
      } else {
        tputs $channel no\n
      }
    }







|







748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
        #
        set version [string map [list v "" . ""] $dotVersion]

        #
        # NOTE: Keep track of the specific image runtime version for usage in
        #       test constraints.
        #
        addConstraint [appendArgs imageRuntime $version]

        tputs $channel [appendArgs $::eagle_platform(imageRuntimeVersion) \
            " " ( $dotVersion ) \n]
      } else {
        tputs $channel no\n
      }
    }
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794

        if {[isMono]} then {
          if {[string length $version] > 0} then {
              #
              # NOTE: We are running on Mono.  Keep track of the specific
              #       version for usage in test constraints.
              #
              addConstraint mono$version
          }

          if {[string length $dotVersion] > 0 && \
              [regexp -- {^(\d+)\.(\d+)$} $dotVersion dummy \
                  majorVersion minorVersion]} then {
            set monoVersions [list]








|







780
781
782
783
784
785
786
787
788
789
790
791
792
793
794

        if {[isMono]} then {
          if {[string length $version] > 0} then {
              #
              # NOTE: We are running on Mono.  Keep track of the specific
              #       version for usage in test constraints.
              #
              addConstraint [appendArgs mono $version]
          }

          if {[string length $dotVersion] > 0 && \
              [regexp -- {^(\d+)\.(\d+)$} $dotVersion dummy \
                  majorVersion minorVersion]} then {
            set monoVersions [list]

863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
          }
        } else {
          if {[string length $version] > 0} then {
            #
            # NOTE: We are running on the .NET Framework.  Keep track of the
            #       specific version for usage in test constraints.
            #
            addConstraint dotNet$version
          }

          #
          # NOTE: We do not want to skip any Mono bugs on .NET.  Add the
          #       necessary constraints for each version of Mono we know
          #       about.
          #







|







863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
          }
        } else {
          if {[string length $version] > 0} then {
            #
            # NOTE: We are running on the .NET Framework.  Keep track of the
            #       specific version for usage in test constraints.
            #
            addConstraint [appendArgs dotNet $version]
          }

          #
          # NOTE: We do not want to skip any Mono bugs on .NET.  Add the
          #       necessary constraints for each version of Mono we know
          #       about.
          #
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
        #       what the caller specified?
        #
        if {$::tcl_platform(machine) eq $machine && \
            $::tcl_platform(osBits) eq $bits} then {
          #
          # NOTE: Yes, it matches.
          #
          addConstraint $machine.${bits}bit

          set result yes
        } else {
          set result no
        }

        tputs $channel [appendArgs $result ", " $::tcl_platform(osBits) -bit \







|







904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
        #       what the caller specified?
        #
        if {$::tcl_platform(machine) eq $machine && \
            $::tcl_platform(osBits) eq $bits} then {
          #
          # NOTE: Yes, it matches.
          #
          addConstraint [appendArgs $machine . $bits bit]

          set result yes
        } else {
          set result no
        }

        tputs $channel [appendArgs $result ", " $::tcl_platform(osBits) -bit \
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
      #
      set culture [info culture]

      if {[string length $culture] > 0} then {
        #
        # NOTE: The culture information is present, use it and show it.
        #
        addConstraint culture.[string map [list - _] $culture]

        tputs $channel [appendArgs $culture \n]
      } else {
        tputs $channel [appendArgs unknown \n]
      }
    }








|







938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
      #
      set culture [info culture]

      if {[string length $culture] > 0} then {
        #
        # NOTE: The culture information is present, use it and show it.
        #
        addConstraint [appendArgs culture. [string map [list - _] $culture]]

        tputs $channel [appendArgs $culture \n]
      } else {
        tputs $channel [appendArgs unknown \n]
      }
    }

975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007

      if {[info exists ::eagle_platform(compileOptions)] && \
          [lsearch -exact -nocase $::eagle_platform(compileOptions) \
              $option] != -1} then {
        #
        # NOTE: Yes, support for the compile option is present.
        #
        addConstraint compile.$option

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForRuntimeOption { channel option } {
      tputs $channel [appendArgs "---- checking for runtime option \"" \
          $option "\"... "]

      if {[info exists ::eagle_platform(runtimeOptions)] && \
          [lsearch -exact -nocase $::eagle_platform(runtimeOptions) \
              $option] != -1} then {
        #
        # NOTE: Yes, support for the runtime option is present.
        #
        addConstraint runtime.$option

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }








|

















|







975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007

      if {[info exists ::eagle_platform(compileOptions)] && \
          [lsearch -exact -nocase $::eagle_platform(compileOptions) \
              $option] != -1} then {
        #
        # NOTE: Yes, support for the compile option is present.
        #
        addConstraint [appendArgs compile. $option]

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

    proc checkForRuntimeOption { channel option } {
      tputs $channel [appendArgs "---- checking for runtime option \"" \
          $option "\"... "]

      if {[info exists ::eagle_platform(runtimeOptions)] && \
          [lsearch -exact -nocase $::eagle_platform(runtimeOptions) \
              $option] != -1} then {
        #
        # NOTE: Yes, support for the runtime option is present.
        #
        addConstraint [appendArgs runtime. $option]

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }

1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171

      if {[catch {object members -flags +NonPublic -pattern $member $object} \
          members] == 0 && [llength $members] > 0} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        if {[string length $constraint] > 0} then {
          addConstraint member_$constraint
        } else {
          addConstraint $object.[string trim $member *?]
        }

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }







|

|







1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171

      if {[catch {object members -flags +NonPublic -pattern $member $object} \
          members] == 0 && [llength $members] > 0} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        if {[string length $constraint] > 0} then {
          addConstraint [appendArgs member_ $constraint]
        } else {
          addConstraint [appendArgs $object. [string trim $member *?]]
        }

        tputs $channel yes\n
      } else {
        tputs $channel no\n
      }
    }
Changes to Externals/Eagle/lib/Test1.0/epilogue.eagle.
19
20
21
22
23
24
25


26
27


28
29
30
31
32
33
34
    error "cannot run, current level is not global"
  }

  if {[isEagle]} then {
    #
    # NOTE: Show the current state of the memory.
    #


    tputs $test_channel [appendArgs "---- ending memory: " \
        [formatListAsDict [debug memory]] \n]



    #
    # NOTE: Show the current state of the native stack.
    #
    catch {debug stack true} stack

    tputs $test_channel [appendArgs "---- ending stack: " \







>
>

|
>
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    error "cannot run, current level is not global"
  }

  if {[isEagle]} then {
    #
    # NOTE: Show the current state of the memory.
    #
    catch {debug memory} memory

    tputs $test_channel [appendArgs "---- ending memory: " \
        [formatListAsDict $memory] \n]

    unset memory

    #
    # NOTE: Show the current state of the native stack.
    #
    catch {debug stack true} stack

    tputs $test_channel [appendArgs "---- ending stack: " \
Changes to Externals/Eagle/lib/Test1.0/prologue.eagle.
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  # NOTE: Has logging been disabled?
  #
  if {![info exists no(log)]} then {
    #
    # NOTE: Set the log to use for test output, if necessary.
    #
    if {![info exists test_log]} then {
      set test_log [file join [getTemporaryPath] [file tail [info \
          nameofexecutable]][getTestLogId].test.[pid].log]
    }
  }

  #
  # NOTE: Evaluate the specified pre-test script now, if any.
  #
  if {[info exists test_flags(-preTest)] && \







|
|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  # NOTE: Has logging been disabled?
  #
  if {![info exists no(log)]} then {
    #
    # NOTE: Set the log to use for test output, if necessary.
    #
    if {![info exists test_log]} then {
      set test_log [file join [getTemporaryPath] [appendArgs [file tail [info \
          nameofexecutable]] [getTestLogId] .test. [pid] .log]]
    }
  }

  #
  # NOTE: Evaluate the specified pre-test script now, if any.
  #
  if {[info exists test_flags(-preTest)] && \
298
299
300
301
302
303
304




































305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324

325
326
327
328

329
330
331
332
333
334
335
      $test_channel \n]

  tputs $test_channel [appendArgs "---- test configuration: " \
      [expr {[info exists test_configuration] ? \
          $test_configuration : "<none>"}] \n]

  if {[isEagle]} then {




































    tputs $test_channel [appendArgs "---- original command line: " \
        [info cmdline] \n]

    tputs $test_channel [appendArgs "---- threadId: " \
        [info tid] \n]

    tputs $test_channel [appendArgs "---- processors: " \
        [info processors] \n]

    catch {object invoke Console.InputEncoding WebName} encoding

    tputs $test_channel [appendArgs "---- input encoding: " \
        $encoding \n]

    catch {object invoke Console.OutputEncoding WebName} encoding

    tputs $test_channel [appendArgs "---- output encoding: " \
        $encoding \n]

    unset encoding


    tputs $test_channel [appendArgs "---- starting memory: " \
        [formatListAsDict [debug memory]] \n]


    catch {debug stack true} stack

    tputs $test_channel [appendArgs "---- starting stack: " \
        [formatListAsDict $stack] \n]

    unset stack
    catch {file drive} drive







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















>


|

>







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
      $test_channel \n]

  tputs $test_channel [appendArgs "---- test configuration: " \
      [expr {[info exists test_configuration] ? \
          $test_configuration : "<none>"}] \n]

  if {[isEagle]} then {
    catch {info engine PublicKeyToken} publicKeyToken

    if {[string length $publicKeyToken] == 0} then {
      #
      # NOTE: The Eagle core library is not strong name signed.  This is not an
      #       error, per se; however, it may cause some tests to fail and it
      #       should be reported to the user and noted in the test suite log
      #       file.
      #
      tputs $test_channel [appendArgs \
          "==== WARNING: running without any strong name signature...\n"]
    } else {
      #
      # BUGBUG: Tcl 8.4 does not like this expression because it contains the
      #         "ni" operator (and Tcl tries to compile it even though it will
      #         only actually ever be evaluated in Eagle).
      #
      set expr {$publicKeyToken ni "29c6297630be05eb 1e22ec67879739a2"}

      if {[expr $expr]} then {
        #
        # NOTE: The Eagle core library is strong name signed with a key that is
        #       not official.  This is also not an error, per se; however, it
        #       may cause some tests to fail and it should be reported to the
        #       user and noted in the test suite log file.
        #
        tputs $test_channel [appendArgs \
            "==== WARNING: running without official strong name signature: " \
            $publicKeyToken \n]
      }

      unset expr
    }

    unset publicKeyToken

    tputs $test_channel [appendArgs "---- original command line: " \
        [info cmdline] \n]

    tputs $test_channel [appendArgs "---- threadId: " \
        [info tid] \n]

    tputs $test_channel [appendArgs "---- processors: " \
        [info processors] \n]

    catch {object invoke Console.InputEncoding WebName} encoding

    tputs $test_channel [appendArgs "---- input encoding: " \
        $encoding \n]

    catch {object invoke Console.OutputEncoding WebName} encoding

    tputs $test_channel [appendArgs "---- output encoding: " \
        $encoding \n]

    unset encoding
    catch {debug memory} memory

    tputs $test_channel [appendArgs "---- starting memory: " \
        [formatListAsDict $memory] \n]

    unset memory
    catch {debug stack true} stack

    tputs $test_channel [appendArgs "---- starting stack: " \
        [formatListAsDict $stack] \n]

    unset stack
    catch {file drive} drive
Changes to System.Data.SQLite/SQLiteConvert.cs.
14
15
16
17
18
19
20











21
22
23
24
25
26
27
  using System.Text;

  /// <summary>
  /// This base class provides datatype conversion services for the SQLite provider.
  /// </summary>
  public abstract class SQLiteConvert
  {











    /// <summary>
    /// An array of ISO8601 datetime formats we support conversion from
    /// </summary>
    private static string[] _datetimeFormats = new string[] {
      "THHmmss",
      "THHmm",
      "HH:mm:ss",







>
>
>
>
>
>
>
>
>
>
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  using System.Text;

  /// <summary>
  /// This base class provides datatype conversion services for the SQLite provider.
  /// </summary>
  public abstract class SQLiteConvert
  {
    /// <summary>
    /// The value for the Unix epoch (e.g. January 1, 1970 at midnight, in UTC).
    /// </summary>
    private static readonly DateTime UnixEpoch =
        new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    /// <summary>
    /// The format string for DateTime values when using the InvariantCulture or CurrentCulture formats.
    /// </summary>
    private const string FullFormat = "yyyy-MM-ddTHH:mm:ss.fffffffK";

    /// <summary>
    /// An array of ISO8601 datetime formats we support conversion from
    /// </summary>
    private static string[] _datetimeFormats = new string[] {
      "THHmmss",
      "THHmm",
      "HH:mm:ss",
139
140
141
142
143
144
145
146



147
148
149
150
151
152
153
154
155






156
157
158
159
160
161
162
    ///   yyyyMMddTHHmmssfffffff
    ///   yyyy-MM-dd
    ///   yy-MM-dd
    ///   yyyyMMdd
    ///   HH:mm:ss
    ///   THHmmss
    /// </remarks>
    /// <param name="dateText">The string containing either a Tick value, a JulianDay double, or an ISO8601-format string</param>



    /// <returns>A DateTime value</returns>
    public DateTime ToDateTime(string dateText)
    {
      switch (_datetimeFormat)
      {
        case SQLiteDateFormats.Ticks:
          return new DateTime(Convert.ToInt64(dateText, CultureInfo.InvariantCulture));
        case SQLiteDateFormats.JulianDay:
          return ToDateTime(Convert.ToDouble(dateText, CultureInfo.InvariantCulture));






        default:
          return DateTime.ParseExact(dateText, _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
      }
    }

    /// <summary>
    /// Converts a julianday value into a DateTime







|
>
>
>









>
>
>
>
>
>







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    ///   yyyyMMddTHHmmssfffffff
    ///   yyyy-MM-dd
    ///   yy-MM-dd
    ///   yyyyMMdd
    ///   HH:mm:ss
    ///   THHmmss
    /// </remarks>
    /// <param name="dateText">The string containing either a long integer number of 100-nanosecond units since
    /// System.DateTime.MinValue, a Julian day double, an integer number of seconds since the Unix epoch, a
    /// culture-independent formatted date and time string, a formatted date and time string in the current
    /// culture, or an ISO8601-format string.</param>
    /// <returns>A DateTime value</returns>
    public DateTime ToDateTime(string dateText)
    {
      switch (_datetimeFormat)
      {
        case SQLiteDateFormats.Ticks:
          return new DateTime(Convert.ToInt64(dateText, CultureInfo.InvariantCulture));
        case SQLiteDateFormats.JulianDay:
          return ToDateTime(Convert.ToDouble(dateText, CultureInfo.InvariantCulture));
        case SQLiteDateFormats.UnixEpoch:
          return UnixEpoch.AddSeconds(Convert.ToInt32(dateText, CultureInfo.InvariantCulture));
        case SQLiteDateFormats.InvariantCulture:
          return DateTime.Parse(dateText, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
        case SQLiteDateFormats.CurrentCulture:
          return DateTime.Parse(dateText, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.None);
        default:
          return DateTime.ParseExact(dateText, _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
      }
    }

    /// <summary>
    /// Converts a julianday value into a DateTime
178
179
180
181
182
183
184
185


186
187
188
189
190
191
192
193






194
195
196
197
198
199
200
      return value.ToOADate() + 2415018.5;
    }

    /// <summary>
    /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <param name="dateValue">The DateTime value to convert</param>
    /// <returns>Either a string consisting of the tick count for DateTimeFormat.Ticks, a JulianDay double, or a date/time in ISO8601 format.</returns>


    public string ToString(DateTime dateValue)
    {
      switch (_datetimeFormat)
      {
        case SQLiteDateFormats.Ticks:
          return dateValue.Ticks.ToString(CultureInfo.InvariantCulture);
        case SQLiteDateFormats.JulianDay:
          return ToJulianDay(dateValue).ToString(CultureInfo.InvariantCulture);






        default:
          return dateValue.ToString(_datetimeFormats[7], CultureInfo.InvariantCulture);
      }
    }

    /// <summary>
    /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime.







|
>
>








>
>
>
>
>
>







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
      return value.ToOADate() + 2415018.5;
    }

    /// <summary>
    /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <param name="dateValue">The DateTime value to convert</param>
    /// <returns>Either a string containing the long integer number of 100-nanosecond units since System.DateTime.MinValue, a
    /// Julian day double, an integer number of seconds since the Unix epoch, a culture-independent formatted date and time
    /// string, a formatted date and time string in the current culture, or an ISO8601-format date/time string.</returns>
    public string ToString(DateTime dateValue)
    {
      switch (_datetimeFormat)
      {
        case SQLiteDateFormats.Ticks:
          return dateValue.Ticks.ToString(CultureInfo.InvariantCulture);
        case SQLiteDateFormats.JulianDay:
          return ToJulianDay(dateValue).ToString(CultureInfo.InvariantCulture);
        case SQLiteDateFormats.UnixEpoch:
          return ((long)(dateValue.Subtract(UnixEpoch).Ticks / TimeSpan.TicksPerSecond)).ToString();
        case SQLiteDateFormats.InvariantCulture:
          return dateValue.ToString(FullFormat, CultureInfo.InvariantCulture);
        case SQLiteDateFormats.CurrentCulture:
          return dateValue.ToString(FullFormat, CultureInfo.CurrentCulture);
        default:
          return dateValue.ToString(_datetimeFormats[7], CultureInfo.InvariantCulture);
      }
    }

    /// <summary>
    /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime.
662
663
664
665
666
667
668

669
670
671
672
673
674
675
      new SQLiteTypeNames("BOOL", DbType.Boolean),
      new SQLiteTypeNames("NUMERIC", DbType.Decimal),
      new SQLiteTypeNames("DECIMAL", DbType.Decimal),
      new SQLiteTypeNames("MONEY", DbType.Decimal),
      new SQLiteTypeNames("CURRENCY", DbType.Decimal),
      new SQLiteTypeNames("TIME", DbType.DateTime),
      new SQLiteTypeNames("DATE", DbType.DateTime),

      new SQLiteTypeNames("SMALLDATE", DbType.DateTime),
      new SQLiteTypeNames("BLOB", DbType.Binary),
      new SQLiteTypeNames("BINARY", DbType.Binary),
      new SQLiteTypeNames("VARBINARY", DbType.Binary),
      new SQLiteTypeNames("IMAGE", DbType.Binary),
      new SQLiteTypeNames("GENERAL", DbType.Binary),
      new SQLiteTypeNames("OLEOBJECT", DbType.Binary),







>







690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
      new SQLiteTypeNames("BOOL", DbType.Boolean),
      new SQLiteTypeNames("NUMERIC", DbType.Decimal),
      new SQLiteTypeNames("DECIMAL", DbType.Decimal),
      new SQLiteTypeNames("MONEY", DbType.Decimal),
      new SQLiteTypeNames("CURRENCY", DbType.Decimal),
      new SQLiteTypeNames("TIME", DbType.DateTime),
      new SQLiteTypeNames("DATE", DbType.DateTime),
      new SQLiteTypeNames("DATETIME", DbType.DateTime),
      new SQLiteTypeNames("SMALLDATE", DbType.DateTime),
      new SQLiteTypeNames("BLOB", DbType.Binary),
      new SQLiteTypeNames("BINARY", DbType.Binary),
      new SQLiteTypeNames("VARBINARY", DbType.Binary),
      new SQLiteTypeNames("IMAGE", DbType.Binary),
      new SQLiteTypeNames("GENERAL", DbType.Binary),
      new SQLiteTypeNames("OLEOBJECT", DbType.Binary),
745
746
747
748
749
750
751












752
753
754
755
756
757
758
    /// The ISO8601 format
    /// </summary>
    ISO8601 = 1,
    /// <summary>
    /// JulianDay format, which is what SQLite uses internally
    /// </summary>
    JulianDay = 2,












    /// <summary>
    /// The default format for this provider.
    /// </summary>
    Default = ISO8601
  }

  /// <summary>







>
>
>
>
>
>
>
>
>
>
>
>







774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
    /// The ISO8601 format
    /// </summary>
    ISO8601 = 1,
    /// <summary>
    /// JulianDay format, which is what SQLite uses internally
    /// </summary>
    JulianDay = 2,
    /// <summary>
    /// The whole number of seconds since the Unix epoch (January 1, 1970).
    /// </summary>
    UnixEpoch = 3,
    /// <summary>
    /// Any culture-independent string value that the .NET Framework can interpret as a valid DateTime.
    /// </summary>
    InvariantCulture = 4,
    /// <summary>
    /// Any string value that the .NET Framework can interpret as a valid DateTime using the current culture.
    /// </summary>
    CurrentCulture = 5,
    /// <summary>
    /// The default format for this provider.
    /// </summary>
    Default = ISO8601
  }

  /// <summary>
Changes to System.Data.SQLite/SQLiteStatement.cs.
173
174
175
176
177
178
179



180


181
182
183
184
185
186
187
        objType = SQLiteConvert.TypeToDbType(obj.GetType());

      switch (objType)
      {
        case DbType.Date:
        case DbType.Time:
        case DbType.DateTime:



          _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, CultureInfo.CurrentCulture));


          break;
        case DbType.Int64:
        case DbType.UInt64:
          _sql.Bind_Int64(this, index, Convert.ToInt64(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Boolean:
        case DbType.Int16:







>
>
>
|
>
>







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
        objType = SQLiteConvert.TypeToDbType(obj.GetType());

      switch (objType)
      {
        case DbType.Date:
        case DbType.Time:
        case DbType.DateTime:
          //
          // NOTE: The old method (commented below) does not honor the selected date format
          //       for the connection.
          // _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, CultureInfo.CurrentCulture));
          _sql.Bind_DateTime(this, index, (obj is string) ?
              _sql.ToDateTime((string)obj) : Convert.ToDateTime(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Int64:
        case DbType.UInt64:
          _sql.Bind_Int64(this, index, Convert.ToInt64(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Boolean:
        case DbType.Int16:
Changes to Tests/basic.eagle.
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

  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 * FROM t1;"

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

  set result
} -cleanup {







|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

  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 {
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587

  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 [array names rows]] {
    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 System.Data.SQLite} \
-result {1 2 2 {1 {{x 1} {y foobar} {z 1234}}} {2 {{x 2} {y foobar} {z 5678}}}\
{count 2} {names {x y z}}}}

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

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







|









|
<







562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

580
581
582
583
584
585
586

  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 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 \
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637

















































































































































































638
639
640
641
642
643
644
645
646

  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 [array names rows]] {
    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 [array names rows]] {
    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 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}}} {count 2} {names {x y z}} 2 {1 {{x 1} {y foobar} {z 1234}}} {2 {{x\
2} {y foobar} {z 5678}}} {count 2} {names {x y z}}}}


















































































































































































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

unset -nocomplain testExeFile testLinqExeFile northwindEfDbFile testLinqOutFile

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

runSQLiteTestEpilogue
runTestEpilogue







|






|










|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822

  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 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 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 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 db fileName
} -constraints \
{eagle culture.en_US monoBug28 command.sql compile.DATA 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