summary refs log tree commit diff stats
path: root/lib/wrappers/odbcsql.nim
blob: 6a27d8355fbc365a6b896e7510905ba490c94c76 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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
162
163
164
165
166
167
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
//: Records contain a fixed number of elements of different types.
:(before "End Mu Types Initialization")
//: We'll use this record as a running example, with two integer elements
int point = Type_number["point"] = Next_type_number++;
Type[point].size = 2;
Type[point].is_record = true;
Type[point].name = "point";
vector<type_number> i;
i.push_back(integer);
Type[point].elements.push_back(i);
Type[point].elements.push_back(i);

:(scenario copy_multiple_locations)
# Records can be copied around with a single instruction just like integers,
# no matter how large they are.
recipe main [
  1:integer <- copy 34:literal
  2:integer <- copy 35:literal
  3:point <- copy 1:point
]
+run: ingredient 0 is 1
+mem: location 1 is 34
+mem: location 2 is 35
+mem: storing 34 in location 3
+mem: storing 35 in location 4

:(before "End Mu Types Initialization")
// A more complex record, containing another record.
int point_integer = Type_number["point-integer"] = Next_type_number++;
Type[point_integer].size = 2;
Type[point_integer].is_record = true;
Type[point_integer].name = "point-integer";
vector<type_number> p2;
p2.push_back(point);
Type[point_integer].elements.push_back(p2);
vector<type_number> i2;
i2.push_back(integer);
Type[point_integer].elements.push_back(i2);

:(scenario "copy_handles_nested_record_elements")
recipe main [
  12:integer <- copy 34:literal
  13:integer <- copy 35:literal
  14:integer <- copy 36:literal
  15:point-integer <- copy 12:point-integer
]
+mem: storing 36 in location 17

:(before "End size_of(types) Cases")
type_info t = Type[types[0]];
if (t.is_record) {
  size_t result = 0;
  for (size_t i = 0; i < t.elements.size(); ++i) {
    result += size_of(t.elements[i]);
  }
  return result;
}

//: To access elements of a record, use 'get'
:(scenario "get")
recipe main [
  12:integer <- copy 34:literal
  13:integer <- copy 35:literal
  15:integer <- get 12:point, 1:offset
]
+run: instruction main/2
+run: ingredient 0 is 12
+run: ingredient 1 is 1
+run: address to copy is 13
+run: its type is 1
+mem: location 13 is 35
+run: product 0 is 35
+mem: storing 35 in location 15

:(before "End Globals")
const int GET = 18;
:(before "End Primitive Recipe Numbers")
Recipe_number["get"] = GET;
assert(Next_recipe_number == GET);
Next_recipe_number++;
:(before "End Primitive Recipe Implementations")
case GET: {
  trace("run") << "ingredient 0 is " << instructions[pc].ingredients[0].name;
  reagent base = instructions[pc].ingredients[0];
  int base_address = base.value;
  int base_type = base.types[0];
  assert(Type[base_type].is_record);
  trace("run") << "ingredient 1 is " << instructions[pc].ingredients[1].name;
  assert(isa_literal(instructions[pc].ingredients[1]));
  size_t offset = instructions[pc].ingredients[1].value;
  int src = base_address;
  for (size_t i = 0; i < offset; ++i) {
    src += size_of(Type[base_type].elements[i]);
  }
  trace("run") << "address to copy is " << src;
  assert(Type[base_type].is_record);
  assert(Type[base_type].elements.size() > offset);
  int src_type = Type[base_type].elements[offset][0];
  trace("run") << "its type is " << src_type;
  reagent tmp;
  tmp.set_value(src);
  tmp.types.push_back(src_type);
  vector<int> result(read_memory(tmp));
  trace("run") << "product 0 is " << result[0];
  write_memory(instructions[pc].products[0], result);
  break;
}

//: 'get' requires a literal in ingredient 1. We'll use a synonym called
//: 'offset'
:(before "End Mu Types Initialization")
Type_number["offset"] = 0;

:(scenario "get_handles_nested_record_elements")
recipe main [
  12:integer <- copy 34:literal
  13:integer <- copy 35:literal
  14:integer <- copy 36:literal
  15:integer <- get 12:point-integer, 1:offset
]
+run: instruction main/2
+run: ingredient 0 is 12
+run: ingredient 1 is 1
+run: address to copy is 14
+run: its type is 1
+mem: location 14 is 36
+run: product 0 is 36
+mem: storing 36 in location 15

:(before "End Globals")
// To write to fields of records, you need their address.
const int GET_ADDRESS = 19;
:(before "End Primitive Recipe Numbers")
Recipe_number["get-address"] = GET_ADDRESS;
assert(Next_recipe_number == GET_ADDRESS);
Next_recipe_number++;
:(before "End Primitive Recipe Implementations")
case GET_ADDRESS: {
  trace("run") << "ingredient 0 is " << instructions[pc].ingredients[0].name;
  reagent base = instructions[pc].ingredients[0];
  int base_address = base.value;
  int base_type = base.types[0];
  assert(Type[base_type].is_record);
  trace("run") << "ingredient 1 is " << instructions[pc].ingredients[1].name;
  assert(isa_literal(instructions[pc].ingredients[1]));
  size_t offset = instructions[pc].ingredients[1].value;
  int src = base_address;
  for (size_t i = 0; i < offset; ++i) {
    src += size_of(Type[base_type].elements[i]);
  }
  trace("run") << "address to copy is " << src;
  vector<int> result;
  result.push_back(src);
  trace("run") << "product 0 is " << result[0];
  write_memory(instructions[pc].products[0], result);
  break;
}

:(scenario "get_address")
recipe main [
  12:integer <- copy 34:literal
  13:integer <- copy 35:literal
  15:address:integer <- get-address 12:point, 1:offset
]
+run: instruction main/2
+run: ingredient 0 is 12
+run: ingredient 1 is 1
+run: address to copy is 13
+mem: storing 13 in location 15
509' href='#n509'>509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 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 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 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 823 824 825 826 827 828 829 830 831 832 833 834 835 836
#
#
#            Nim's Runtime Library
#        (c) Copyright 2015 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

{.deadCodeElim: on.}  # dce option deprecated

when not defined(ODBCVER):
  const
    ODBCVER = 0x0351 ## define ODBC version 3.51 by default

when defined(windows):
  {.push callconv: stdcall.}
  const odbclib = "odbc32.dll"
else:
  {.push callconv: cdecl.}
  const odbclib = "libodbc.so"

# DATA TYPES CORRESPONDENCE
#   BDE fields  ODBC types
#   ----------  ------------------
#   ftBlob      SQL_BINARY
#   ftBoolean   SQL_BIT
#   ftDate      SQL_TYPE_DATE
#   ftTime      SQL_TYPE_TIME
#   ftDateTime  SQL_TYPE_TIMESTAMP
#   ftInteger   SQL_INTEGER
#   ftSmallint  SQL_SMALLINT
#   ftFloat     SQL_DOUBLE
#   ftString    SQL_CHAR
#   ftMemo      SQL_BINARY // SQL_VARCHAR
#

type
  TSqlChar* = char
  TSqlSmallInt* = int16
  SqlUSmallInt* = int16
  SqlHandle* = pointer
  SqlHEnv* = SqlHandle
  SqlHDBC* = SqlHandle
  SqlHStmt* = SqlHandle
  SqlHDesc* = SqlHandle
  TSqlInteger* = int
  SqlUInteger* = int
  SqlPointer* = pointer
  TSqlReal* = cfloat
  TSqlDouble* = cdouble
  TSqlFloat* = cdouble
  SqlHWND* = pointer
  PSQLCHAR* = cstring
  PSQLINTEGER* = ptr TSqlInteger
  PSQLUINTEGER* = ptr SqlUInteger
  PSQLSMALLINT* = ptr TSqlSmallInt
  PSQLUSMALLINT* = ptr SqlUSmallInt
  PSQLREAL* = ptr TSqlReal
  PSQLDOUBLE* = ptr TSqlDouble
  PSQLFLOAT* = ptr TSqlFloat
  PSQLHANDLE* = ptr SqlHandle

const                         # SQL data type codes
  SQL_UNKNOWN_TYPE* = 0
  SQL_LONGVARCHAR* = (- 1)
  SQL_BINARY* = (- 2)
  SQL_VARBINARY* = (- 3)
  SQL_LONGVARBINARY* = (- 4)
  SQL_BIGINT* = (- 5)
  SQL_TINYINT* = (- 6)
  SQL_BIT* = (- 7)
  SQL_WCHAR* = (- 8)
  SQL_WVARCHAR* = (- 9)
  SQL_WLONGVARCHAR* = (- 10)
  SQL_CHAR* = 1
  SQL_NUMERIC* = 2
  SQL_DECIMAL* = 3
  SQL_INTEGER* = 4
  SQL_SMALLINT* = 5
  SQL_FLOAT* = 6
  SQL_REAL* = 7
  SQL_DOUBLE* = 8
  SQL_DATETIME* = 9
  SQL_VARCHAR* = 12
  SQL_TYPE_DATE* = 91
  SQL_TYPE_TIME* = 92
  SQL_TYPE_TIMESTAMP* = 93
  SQL_DATE* = 9
  SQL_TIME* = 10
  SQL_TIMESTAMP* = 11
  SQL_INTERVAL* = 10
  SQL_GUID* = - 11            # interval codes

when ODBCVER >= 0x0300:
  const
    SQL_CODE_YEAR* = 1
    SQL_CODE_MONTH* = 2
    SQL_CODE_DAY* = 3
    SQL_CODE_HOUR* = 4
    SQL_CODE_MINUTE* = 5
    SQL_CODE_SECOND* = 6
    SQL_CODE_YEAR_TO_MONTH* = 7
    SQL_CODE_DAY_TO_HOUR* = 8
    SQL_CODE_DAY_TO_MINUTE* = 9
    SQL_CODE_DAY_TO_SECOND* = 10
    SQL_CODE_HOUR_TO_MINUTE* = 11
    SQL_CODE_HOUR_TO_SECOND* = 12
    SQL_CODE_MINUTE_TO_SECOND* = 13
    SQL_INTERVAL_YEAR* = 100 + SQL_CODE_YEAR
    SQL_INTERVAL_MONTH* = 100 + SQL_CODE_MONTH
    SQL_INTERVAL_DAY* = 100 + SQL_CODE_DAY
    SQL_INTERVAL_HOUR* = 100 + SQL_CODE_HOUR
    SQL_INTERVAL_MINUTE* = 100 + SQL_CODE_MINUTE
    SQL_INTERVAL_SECOND* = 100 + SQL_CODE_SECOND
    SQL_INTERVAL_YEAR_TO_MONTH* = 100 + SQL_CODE_YEAR_TO_MONTH
    SQL_INTERVAL_DAY_TO_HOUR* = 100 + SQL_CODE_DAY_TO_HOUR
    SQL_INTERVAL_DAY_TO_MINUTE* = 100 + SQL_CODE_DAY_TO_MINUTE
    SQL_INTERVAL_DAY_TO_SECOND* = 100 + SQL_CODE_DAY_TO_SECOND
    SQL_INTERVAL_HOUR_TO_MINUTE* = 100 + SQL_CODE_HOUR_TO_MINUTE
    SQL_INTERVAL_HOUR_TO_SECOND* = 100 + SQL_CODE_HOUR_TO_SECOND
    SQL_INTERVAL_MINUTE_TO_SECOND* = 100 + SQL_CODE_MINUTE_TO_SECOND
else:
  const
    SQL_INTERVAL_YEAR* = - 80
    SQL_INTERVAL_MONTH* = - 81
    SQL_INTERVAL_YEAR_TO_MONTH* = - 82
    SQL_INTERVAL_DAY* = - 83
    SQL_INTERVAL_HOUR* = - 84
    SQL_INTERVAL_MINUTE* = - 85
    SQL_INTERVAL_SECOND* = - 86
    SQL_INTERVAL_DAY_TO_HOUR* = - 87
    SQL_INTERVAL_DAY_TO_MINUTE* = - 88
    SQL_INTERVAL_DAY_TO_SECOND* = - 89
    SQL_INTERVAL_HOUR_TO_MINUTE* = - 90
    SQL_INTERVAL_HOUR_TO_SECOND* = - 91
    SQL_INTERVAL_MINUTE_TO_SECOND* = - 92


when ODBCVER < 0x0300:
  const
    SQL_UNICODE* = - 95
    SQL_UNICODE_VARCHAR* = - 96
    SQL_UNICODE_LONGVARCHAR* = - 97
    SQL_UNICODE_CHAR* = SQL_UNICODE
else:
  # The previous definitions for SQL_UNICODE_ are historical and obsolete
  const
    SQL_UNICODE* = SQL_WCHAR
    SQL_UNICODE_VARCHAR* = SQL_WVARCHAR
    SQL_UNICODE_LONGVARCHAR* = SQL_WLONGVARCHAR
    SQL_UNICODE_CHAR* = SQL_WCHAR
const                         # C datatype to SQL datatype mapping
  SQL_C_CHAR* = SQL_CHAR
  SQL_C_LONG* = SQL_INTEGER
  SQL_C_SHORT* = SQL_SMALLINT
  SQL_C_FLOAT* = SQL_REAL
  SQL_C_DOUBLE* = SQL_DOUBLE
  SQL_C_NUMERIC* = SQL_NUMERIC
  SQL_C_DEFAULT* = 99
  SQL_SIGNED_OFFSET* = - 20
  SQL_UNSIGNED_OFFSET* = - 22
  SQL_C_DATE* = SQL_DATE
  SQL_C_TIME* = SQL_TIME
  SQL_C_TIMESTAMP* = SQL_TIMESTAMP
  SQL_C_TYPE_DATE* = SQL_TYPE_DATE
  SQL_C_TYPE_TIME* = SQL_TYPE_TIME
  SQL_C_TYPE_TIMESTAMP* = SQL_TYPE_TIMESTAMP
  SQL_C_INTERVAL_YEAR* = SQL_INTERVAL_YEAR
  SQL_C_INTERVAL_MONTH* = SQL_INTERVAL_MONTH
  SQL_C_INTERVAL_DAY* = SQL_INTERVAL_DAY
  SQL_C_INTERVAL_HOUR* = SQL_INTERVAL_HOUR
  SQL_C_INTERVAL_MINUTE* = SQL_INTERVAL_MINUTE
  SQL_C_INTERVAL_SECOND* = SQL_INTERVAL_SECOND
  SQL_C_INTERVAL_YEAR_TO_MONTH* = SQL_INTERVAL_YEAR_TO_MONTH
  SQL_C_INTERVAL_DAY_TO_HOUR* = SQL_INTERVAL_DAY_TO_HOUR
  SQL_C_INTERVAL_DAY_TO_MINUTE* = SQL_INTERVAL_DAY_TO_MINUTE
  SQL_C_INTERVAL_DAY_TO_SECOND* = SQL_INTERVAL_DAY_TO_SECOND
  SQL_C_INTERVAL_HOUR_TO_MINUTE* = SQL_INTERVAL_HOUR_TO_MINUTE
  SQL_C_INTERVAL_HOUR_TO_SECOND* = SQL_INTERVAL_HOUR_TO_SECOND
  SQL_C_INTERVAL_MINUTE_TO_SECOND* = SQL_INTERVAL_MINUTE_TO_SECOND
  SQL_C_BINARY* = SQL_BINARY
  SQL_C_BIT* = SQL_BIT
  SQL_C_SBIGINT* = SQL_BIGINT + SQL_SIGNED_OFFSET # SIGNED BIGINT
  SQL_C_UBIGINT* = SQL_BIGINT + SQL_UNSIGNED_OFFSET # UNSIGNED BIGINT
  SQL_C_TINYINT* = SQL_TINYINT
  SQL_C_SLONG* = SQL_C_LONG + SQL_SIGNED_OFFSET # SIGNED INTEGER
  SQL_C_SSHORT* = SQL_C_SHORT + SQL_SIGNED_OFFSET # SIGNED SMALLINT
  SQL_C_STINYINT* = SQL_TINYINT + SQL_SIGNED_OFFSET # SIGNED TINYINT
  SQL_C_ULONG* = SQL_C_LONG + SQL_UNSIGNED_OFFSET # UNSIGNED INTEGER
  SQL_C_USHORT* = SQL_C_SHORT + SQL_UNSIGNED_OFFSET # UNSIGNED SMALLINT
  SQL_C_UTINYINT* = SQL_TINYINT + SQL_UNSIGNED_OFFSET # UNSIGNED TINYINT
  SQL_C_BOOKMARK* = SQL_C_ULONG # BOOKMARK
  SQL_C_GUID* = SQL_GUID
  SQL_TYPE_NULL* = 0

when ODBCVER < 0x0300:
  const
    SQL_TYPE_MIN* = SQL_BIT
    SQL_TYPE_MAX* = SQL_VARCHAR

const
  SQL_C_VARBOOKMARK* = SQL_C_BINARY
  SQL_API_SQLDESCRIBEPARAM* = 58
  SQL_NO_TOTAL* = - 4

type
  SQL_DATE_STRUCT* {.final, pure.} = object
    Year*: TSqlSmallInt
    Month*: SqlUSmallInt
    Day*: SqlUSmallInt

  PSQL_DATE_STRUCT* = ptr SQL_DATE_STRUCT
  SQL_TIME_STRUCT* {.final, pure.} = object
    Hour*: SqlUSmallInt
    Minute*: SqlUSmallInt
    Second*: SqlUSmallInt

  PSQL_TIME_STRUCT* = ptr SQL_TIME_STRUCT
  SQL_TIMESTAMP_STRUCT* {.final, pure.} = object
    Year*: SqlUSmallInt
    Month*: SqlUSmallInt
    Day*: SqlUSmallInt
    Hour*: SqlUSmallInt
    Minute*: SqlUSmallInt
    Second*: SqlUSmallInt
    Fraction*: SqlUInteger

  PSQL_TIMESTAMP_STRUCT* = ptr SQL_TIMESTAMP_STRUCT

const
  SQL_NAME_LEN* = 128
  SQL_OV_ODBC3* = 3
  SQL_OV_ODBC2* = 2
  SQL_ATTR_ODBC_VERSION* = 200 # Options for SQLDriverConnect
  SQL_DRIVER_NOPROMPT* = 0
  SQL_DRIVER_COMPLETE* = 1
  SQL_DRIVER_PROMPT* = 2
  SQL_DRIVER_COMPLETE_REQUIRED* = 3
  SQL_IS_POINTER* = (- 4)  # whether an attribute is a pointer or not
  SQL_IS_UINTEGER* = (- 5)
  SQL_IS_INTEGER* = (- 6)
  SQL_IS_USMALLINT* = (- 7)
  SQL_IS_SMALLINT* = (- 8)    # SQLExtendedFetch "fFetchType" values
  SQL_FETCH_BOOKMARK* = 8
  SQL_SCROLL_OPTIONS* = 44    # SQL_USE_BOOKMARKS options
  SQL_UB_OFF* = 0
  SQL_UB_ON* = 1
  SQL_UB_DEFAULT* = SQL_UB_OFF
  SQL_UB_FIXED* = SQL_UB_ON
  SQL_UB_VARIABLE* = 2        # SQL_SCROLL_OPTIONS masks
  SQL_SO_FORWARD_ONLY* = 0x00000001
  SQL_SO_KEYSET_DRIVEN* = 0x00000002
  SQL_SO_DYNAMIC* = 0x00000004
  SQL_SO_MIXED* = 0x00000008
  SQL_SO_STATIC* = 0x00000010
  SQL_BOOKMARK_PERSISTENCE* = 82
  SQL_STATIC_SENSITIVITY* = 83 # SQL_BOOKMARK_PERSISTENCE values
  SQL_BP_CLOSE* = 0x00000001
  SQL_BP_DELETE* = 0x00000002
  SQL_BP_DROP* = 0x00000004
  SQL_BP_TRANSACTION* = 0x00000008
  SQL_BP_UPDATE* = 0x00000010
  SQL_BP_OTHER_HSTMT* = 0x00000020
  SQL_BP_SCROLL* = 0x00000040
  SQL_DYNAMIC_CURSOR_ATTRIBUTES1* = 144
  SQL_DYNAMIC_CURSOR_ATTRIBUTES2* = 145
  SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1* = 146
  SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2* = 147
  SQL_INDEX_KEYWORDS* = 148
  SQL_INFO_SCHEMA_VIEWS* = 149
  SQL_KEYSET_CURSOR_ATTRIBUTES1* = 150
  SQL_KEYSET_CURSOR_ATTRIBUTES2* = 151
  SQL_STATIC_CURSOR_ATTRIBUTES1* = 167
  SQL_STATIC_CURSOR_ATTRIBUTES2* = 168 # supported SQLFetchScroll FetchOrientation's
  SQL_CA1_NEXT* = 1
  SQL_CA1_ABSOLUTE* = 2
  SQL_CA1_RELATIVE* = 4
  SQL_CA1_BOOKMARK* = 8       # supported SQLSetPos LockType's
  SQL_CA1_LOCK_NO_CHANGE* = 0x00000040
  SQL_CA1_LOCK_EXCLUSIVE* = 0x00000080
  SQL_CA1_LOCK_UNLOCK* = 0x00000100 # supported SQLSetPos Operations
  SQL_CA1_POS_POSITION* = 0x00000200
  SQL_CA1_POS_UPDATE* = 0x00000400
  SQL_CA1_POS_DELETE* = 0x00000800
  SQL_CA1_POS_REFRESH* = 0x00001000 # positioned updates and deletes
  SQL_CA1_POSITIONED_UPDATE* = 0x00002000
  SQL_CA1_POSITIONED_DELETE* = 0x00004000
  SQL_CA1_SELECT_FOR_UPDATE* = 0x00008000 # supported SQLBulkOperations operations
  SQL_CA1_BULK_ADD* = 0x00010000
  SQL_CA1_BULK_UPDATE_BY_BOOKMARK* = 0x00020000
  SQL_CA1_BULK_DELETE_BY_BOOKMARK* = 0x00040000
  SQL_CA1_BULK_FETCH_BY_BOOKMARK* = 0x00080000 # supported values for SQL_ATTR_SCROLL_CONCURRENCY
  SQL_CA2_READ_ONLY_CONCURRENCY* = 1
  SQL_CA2_LOCK_CONCURRENCY* = 2
  SQL_CA2_OPT_ROWVER_CONCURRENCY* = 4
  SQL_CA2_OPT_VALUES_CONCURRENCY* = 8 # sensitivity of the cursor to its own inserts, deletes, and updates
  SQL_CA2_SENSITIVITY_ADDITIONS* = 0x00000010
  SQL_CA2_SENSITIVITY_DELETIONS* = 0x00000020
  SQL_CA2_SENSITIVITY_UPDATES* = 0x00000040 #  semantics of SQL_ATTR_MAX_ROWS
  SQL_CA2_MAX_ROWS_SELECT* = 0x00000080
  SQL_CA2_MAX_ROWS_INSERT* = 0x00000100
  SQL_CA2_MAX_ROWS_DELETE* = 0x00000200
  SQL_CA2_MAX_ROWS_UPDATE* = 0x00000400
  SQL_CA2_MAX_ROWS_CATALOG* = 0x00000800
  SQL_CA2_MAX_ROWS_AFFECTS_ALL* = (SQL_CA2_MAX_ROWS_SELECT or
      SQL_CA2_MAX_ROWS_INSERT or SQL_CA2_MAX_ROWS_DELETE or
      SQL_CA2_MAX_ROWS_UPDATE or SQL_CA2_MAX_ROWS_CATALOG) # semantics of
                                                           # SQL_DIAG_CURSOR_ROW_COUNT
  SQL_CA2_CRC_EXACT* = 0x00001000
  SQL_CA2_CRC_APPROXIMATE* = 0x00002000 #  the kinds of positioned statements that can be simulated
  SQL_CA2_SIMULATE_NON_UNIQUE* = 0x00004000
  SQL_CA2_SIMULATE_TRY_UNIQUE* = 0x00008000
  SQL_CA2_SIMULATE_UNIQUE* = 0x00010000 #  Operations in SQLBulkOperations
  SQL_ADD* = 4
  SQL_SETPOS_MAX_OPTION_VALUE* = SQL_ADD
  SQL_UPDATE_BY_BOOKMARK* = 5
  SQL_DELETE_BY_BOOKMARK* = 6
  SQL_FETCH_BY_BOOKMARK* = 7  # Operations in SQLSetPos
  SQL_POSITION* = 0
  SQL_REFRESH* = 1
  SQL_UPDATE* = 2
  SQL_DELETE* = 3             # Lock options in SQLSetPos
  SQL_LOCK_NO_CHANGE* = 0
  SQL_LOCK_EXCLUSIVE* = 1
  SQL_LOCK_UNLOCK* = 2        # SQLExtendedFetch "rgfRowStatus" element values
  SQL_ROW_SUCCESS* = 0
  SQL_ROW_DELETED* = 1
  SQL_ROW_UPDATED* = 2
  SQL_ROW_NOROW* = 3
  SQL_ROW_ADDED* = 4
  SQL_ROW_ERROR* = 5
  SQL_ROW_SUCCESS_WITH_INFO* = 6
  SQL_ROW_PROCEED* = 0
  SQL_ROW_IGNORE* = 1
  SQL_MAX_DSN_LENGTH* = 32    # maximum data source name size
  SQL_MAX_OPTION_STRING_LENGTH* = 256
  SQL_ODBC_CURSORS* = 110
  SQL_ATTR_ODBC_CURSORS* = SQL_ODBC_CURSORS # SQL_ODBC_CURSORS options
  SQL_CUR_USE_IF_NEEDED* = 0
  SQL_CUR_USE_ODBC* = 1
  SQL_CUR_USE_DRIVER* = 2
  SQL_CUR_DEFAULT* = SQL_CUR_USE_DRIVER
  SQL_PARAM_TYPE_UNKNOWN* = 0
  SQL_PARAM_INPUT* = 1
  SQL_PARAM_INPUT_OUTPUT* = 2
  SQL_RESULT_COL* = 3
  SQL_PARAM_OUTPUT* = 4
  SQL_RETURN_VALUE* = 5       # special length/indicator values
  SQL_NULL_DATA* = (- 1)
  SQL_DATA_AT_EXEC* = (- 2)
  SQL_SUCCESS* = 0
  SQL_SUCCESS_WITH_INFO* = 1
  SQL_NO_DATA* = 100
  SQL_ERROR* = (- 1)
  SQL_INVALID_HANDLE* = (- 2)
  SQL_STILL_EXECUTING* = 2
  SQL_NEED_DATA* = 99         # flags for null-terminated string
  SQL_NTS* = (- 3)            # maximum message length
  SQL_MAX_MESSAGE_LENGTH* = 512 # date/time length constants
  SQL_DATE_LEN* = 10
  SQL_TIME_LEN* = 8           # add P+1 if precision is nonzero
  SQL_TIMESTAMP_LEN* = 19     # add P+1 if precision is nonzero
                              # handle type identifiers
  SQL_HANDLE_ENV* = 1
  SQL_HANDLE_DBC* = 2
  SQL_HANDLE_STMT* = 3
  SQL_HANDLE_DESC* = 4        # environment attribute
  SQL_ATTR_OUTPUT_NTS* = 10001 # connection attributes
  SQL_ATTR_AUTO_IPD* = 10001
  SQL_ATTR_METADATA_ID* = 10014 # statement attributes
  SQL_ATTR_APP_ROW_DESC* = 10010
  SQL_ATTR_APP_PARAM_DESC* = 10011
  SQL_ATTR_IMP_ROW_DESC* = 10012
  SQL_ATTR_IMP_PARAM_DESC* = 10013
  SQL_ATTR_CURSOR_SCROLLABLE* = (- 1)
  SQL_ATTR_CURSOR_SENSITIVITY* = (- 2)
  SQL_QUERY_TIMEOUT* = 0
  SQL_MAX_ROWS* = 1
  SQL_NOSCAN* = 2
  SQL_MAX_LENGTH* = 3
  SQL_ASYNC_ENABLE* = 4       # same as SQL_ATTR_ASYNC_ENABLE */
  SQL_BIND_TYPE* = 5
  SQL_CURSOR_TYPE* = 6
  SQL_CONCURRENCY* = 7
  SQL_KEYSET_SIZE* = 8
  SQL_ROWSET_SIZE* = 9
  SQL_SIMULATE_CURSOR* = 10
  SQL_RETRIEVE_DATA* = 11
  SQL_USE_BOOKMARKS* = 12
  SQL_GET_BOOKMARK* = 13      #      GetStmtOption Only */
  SQL_ROW_NUMBER* = 14        #      GetStmtOption Only */
  SQL_ATTR_CURSOR_TYPE* = SQL_CURSOR_TYPE
  SQL_ATTR_CONCURRENCY* = SQL_CONCURRENCY
  SQL_ATTR_FETCH_BOOKMARK_PTR* = 16
  SQL_ATTR_ROW_STATUS_PTR* = 25
  SQL_ATTR_ROWS_FETCHED_PTR* = 26
  SQL_AUTOCOMMIT* = 102
  SQL_ATTR_AUTOCOMMIT* = SQL_AUTOCOMMIT
  SQL_ATTR_ROW_NUMBER* = SQL_ROW_NUMBER
  SQL_TXN_ISOLATION* = 108
  SQL_ATTR_TXN_ISOLATION* = SQL_TXN_ISOLATION
  SQL_ATTR_MAX_ROWS* = SQL_MAX_ROWS
  SQL_ATTR_USE_BOOKMARKS* = SQL_USE_BOOKMARKS #* connection attributes */
  SQL_ACCESS_MODE* = 101      #  SQL_AUTOCOMMIT              =102;
  SQL_LOGIN_TIMEOUT* = 103
  SQL_OPT_TRACE* = 104
  SQL_OPT_TRACEFILE* = 105
  SQL_TRANSLATE_DLL* = 106
  SQL_TRANSLATE_OPTION* = 107 #  SQL_TXN_ISOLATION           =108;
  SQL_CURRENT_QUALIFIER* = 109 #  SQL_ODBC_CURSORS            =110;
  SQL_QUIET_MODE* = 111
  SQL_PACKET_SIZE* = 112      #* connection attributes with new names */
  SQL_ATTR_ACCESS_MODE* = SQL_ACCESS_MODE #  SQL_ATTR_AUTOCOMMIT                       =SQL_AUTOCOMMIT;
  SQL_ATTR_CONNECTION_DEAD* = 1209 #* GetConnectAttr only */
  SQL_ATTR_CONNECTION_TIMEOUT* = 113
  SQL_ATTR_CURRENT_CATALOG* = SQL_CURRENT_QUALIFIER
  SQL_ATTR_DISCONNECT_BEHAVIOR* = 114
  SQL_ATTR_ENLIST_IN_DTC* = 1207
  SQL_ATTR_ENLIST_IN_XA* = 1208
  SQL_ATTR_LOGIN_TIMEOUT* = SQL_LOGIN_TIMEOUT #  SQL_ATTR_ODBC_CURSORS             =SQL_ODBC_CURSORS;
  SQL_ATTR_PACKET_SIZE* = SQL_PACKET_SIZE
  SQL_ATTR_QUIET_MODE* = SQL_QUIET_MODE
  SQL_ATTR_TRACE* = SQL_OPT_TRACE
  SQL_ATTR_TRACEFILE* = SQL_OPT_TRACEFILE
  SQL_ATTR_TRANSLATE_LIB* = SQL_TRANSLATE_DLL
  SQL_ATTR_TRANSLATE_OPTION* = SQL_TRANSLATE_OPTION #  SQL_ATTR_TXN_ISOLATION                  =SQL_TXN_ISOLATION;
                                                    #* SQL_ACCESS_MODE options */
  SQL_MODE_READ_WRITE* = 0
  SQL_MODE_READ_ONLY* = 1
  SQL_MODE_DEFAULT* = SQL_MODE_READ_WRITE #* SQL_AUTOCOMMIT options */
  SQL_AUTOCOMMIT_OFF* = 0
  SQL_AUTOCOMMIT_ON* = 1
  SQL_AUTOCOMMIT_DEFAULT* = SQL_AUTOCOMMIT_ON # SQL_ATTR_CURSOR_SCROLLABLE values
  SQL_NONSCROLLABLE* = 0
  SQL_SCROLLABLE* = 1         # SQL_CURSOR_TYPE options
  SQL_CURSOR_FORWARD_ONLY* = 0
  SQL_CURSOR_KEYSET_DRIVEN* = 1
  SQL_CURSOR_DYNAMIC* = 2
  SQL_CURSOR_STATIC* = 3
  SQL_CURSOR_TYPE_DEFAULT* = SQL_CURSOR_FORWARD_ONLY # Default value
                                                     # SQL_CONCURRENCY options
  SQL_CONCUR_READ_ONLY* = 1
  SQL_CONCUR_LOCK* = 2
  SQL_CONCUR_ROWVER* = 3
  SQL_CONCUR_VALUES* = 4
  SQL_CONCUR_DEFAULT* = SQL_CONCUR_READ_ONLY # Default value
                                             # identifiers of fields in the SQL descriptor
  SQL_DESC_COUNT* = 1001
  SQL_DESC_TYPE* = 1002
  SQL_DESC_LENGTH* = 1003
  SQL_DESC_OCTET_LENGTH_PTR* = 1004
  SQL_DESC_PRECISION* = 1005
  SQL_DESC_SCALE* = 1006
  SQL_DESC_DATETIME_INTERVAL_CODE* = 1007
  SQL_DESC_NULLABLE* = 1008
  SQL_DESC_INDICATOR_PTR* = 1009
  SQL_DESC_DATA_PTR* = 1010
  SQL_DESC_NAME* = 1011
  SQL_DESC_UNNAMED* = 1012
  SQL_DESC_OCTET_LENGTH* = 1013
  SQL_DESC_ALLOC_TYPE* = 1099 # identifiers of fields in the diagnostics area
  SQL_DIAG_RETURNCODE* = 1
  SQL_DIAG_NUMBER* = 2
  SQL_DIAG_ROW_COUNT* = 3
  SQL_DIAG_SQLSTATE* = 4
  SQL_DIAG_NATIVE* = 5
  SQL_DIAG_MESSAGE_TEXT* = 6
  SQL_DIAG_DYNAMIC_FUNCTION* = 7
  SQL_DIAG_CLASS_ORIGIN* = 8
  SQL_DIAG_SUBCLASS_ORIGIN* = 9
  SQL_DIAG_CONNECTION_NAME* = 10
  SQL_DIAG_SERVER_NAME* = 11
  SQL_DIAG_DYNAMIC_FUNCTION_CODE* = 12 # dynamic function codes
  SQL_DIAG_ALTER_TABLE* = 4
  SQL_DIAG_CREATE_INDEX* = (- 1)
  SQL_DIAG_CREATE_TABLE* = 77
  SQL_DIAG_CREATE_VIEW* = 84
  SQL_DIAG_DELETE_WHERE* = 19
  SQL_DIAG_DROP_INDEX* = (- 2)
  SQL_DIAG_DROP_TABLE* = 32
  SQL_DIAG_DROP_VIEW* = 36
  SQL_DIAG_DYNAMIC_DELETE_CURSOR* = 38
  SQL_DIAG_DYNAMIC_UPDATE_CURSOR* = 81
  SQL_DIAG_GRANT* = 48
  SQL_DIAG_INSERT* = 50
  SQL_DIAG_REVOKE* = 59
  SQL_DIAG_SELECT_CURSOR* = 85
  SQL_DIAG_UNKNOWN_STATEMENT* = 0
  SQL_DIAG_UPDATE_WHERE* = 82 # Statement attribute values for cursor sensitivity
  SQL_UNSPECIFIED* = 0
  SQL_INSENSITIVE* = 1
  SQL_SENSITIVE* = 2          # GetTypeInfo() request for all data types
  SQL_ALL_TYPES* = 0          # Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData()
  SQL_DEFAULT* = 99 # SQLGetData() code indicating that the application row descriptor
                    #    specifies the data type
  SQL_ARD_TYPE* = (- 99)      # SQL date/time type subcodes
  SQL_CODE_DATE* = 1
  SQL_CODE_TIME* = 2
  SQL_CODE_TIMESTAMP* = 3     # CLI option values
  SQL_FALSE* = 0
  SQL_TRUE* = 1               # values of NULLABLE field in descriptor
  SQL_NO_NULLS* = 0
  SQL_NULLABLE* = 1 # Value returned by SQLGetTypeInfo() to denote that it is
                    # not known whether or not a data type supports null values.
  SQL_NULLABLE_UNKNOWN* = 2
  SQL_CLOSE* = 0
  SQL_DROP* = 1
  SQL_UNBIND* = 2
  SQL_RESET_PARAMS* = 3 # Codes used for FetchOrientation in SQLFetchScroll(),
                        #   and in SQLDataSources()
  SQL_FETCH_NEXT* = 1
  SQL_FETCH_FIRST* = 2
  SQL_FETCH_FIRST_USER* = 31
  SQL_FETCH_FIRST_SYSTEM* = 32 # Other codes used for FetchOrientation in SQLFetchScroll()
  SQL_FETCH_LAST* = 3
  SQL_FETCH_PRIOR* = 4
  SQL_FETCH_ABSOLUTE* = 5
  SQL_FETCH_RELATIVE* = 6
  SQL_NULL_HENV* = SqlHEnv(nil)
  SQL_NULL_HDBC* = SqlHDBC(nil)
  SQL_NULL_HSTMT* = SqlHStmt(nil)
  SQL_NULL_HDESC* = SqlHDesc(nil) #* null handle used in place of parent handle when allocating HENV */
  SQL_NULL_HANDLE* = SqlHandle(nil) #* Values that may appear in the result set of SQLSpecialColumns() */
  SQL_SCOPE_CURROW* = 0
  SQL_SCOPE_TRANSACTION* = 1
  SQL_SCOPE_SESSION* = 2      #* Column types and scopes in SQLSpecialColumns.  */
  SQL_BEST_ROWID* = 1
  SQL_ROWVER* = 2
  SQL_ROW_IDENTIFIER* = 1     #* Reserved values for UNIQUE argument of SQLStatistics() */
  SQL_INDEX_UNIQUE* = 0
  SQL_INDEX_ALL* = 1          #* Reserved values for RESERVED argument of SQLStatistics() */
  SQL_QUICK* = 0
  SQL_ENSURE* = 1             #* Values that may appear in the result set of SQLStatistics() */
  SQL_TABLE_STAT* = 0
  SQL_INDEX_CLUSTERED* = 1
  SQL_INDEX_HASHED* = 2
  SQL_INDEX_OTHER* = 3
  SQL_SCROLL_CONCURRENCY* = 43
  SQL_TXN_CAPABLE* = 46
  SQL_TRANSACTION_CAPABLE* = SQL_TXN_CAPABLE
  SQL_USER_NAME* = 47
  SQL_TXN_ISOLATION_OPTION* = 72
  SQL_TRANSACTION_ISOLATION_OPTION* = SQL_TXN_ISOLATION_OPTION
  SQL_OJ_CAPABILITIES* = 115
  SQL_OUTER_JOIN_CAPABILITIES* = SQL_OJ_CAPABILITIES
  SQL_XOPEN_CLI_YEAR* = 10000
  SQL_CURSOR_SENSITIVITY* = 10001
  SQL_DESCRIBE_PARAMETER* = 10002
  SQL_CATALOG_NAME* = 10003
  SQL_COLLATION_SEQ* = 10004
  SQL_MAX_IDENTIFIER_LEN* = 10005
  SQL_MAXIMUM_IDENTIFIER_LENGTH* = SQL_MAX_IDENTIFIER_LEN
  SQL_SCCO_READ_ONLY* = 1
  SQL_SCCO_LOCK* = 2
  SQL_SCCO_OPT_ROWVER* = 4
  SQL_SCCO_OPT_VALUES* = 8    #* SQL_TXN_CAPABLE values */
  SQL_TC_NONE* = 0
  SQL_TC_DML* = 1
  SQL_TC_ALL* = 2
  SQL_TC_DDL_COMMIT* = 3
  SQL_TC_DDL_IGNORE* = 4      #* SQL_TXN_ISOLATION_OPTION bitmasks */
  SQL_TXN_READ_UNCOMMITTED* = 1
  SQL_TRANSACTION_READ_UNCOMMITTED* = SQL_TXN_READ_UNCOMMITTED
  SQL_TXN_READ_COMMITTED* = 2
  SQL_TRANSACTION_READ_COMMITTED* = SQL_TXN_READ_COMMITTED
  SQL_TXN_REPEATABLE_READ* = 4
  SQL_TRANSACTION_REPEATABLE_READ* = SQL_TXN_REPEATABLE_READ
  SQL_TXN_SERIALIZABLE* = 8
  SQL_TRANSACTION_SERIALIZABLE* = SQL_TXN_SERIALIZABLE
  SQL_SS_ADDITIONS* = 1
  SQL_SS_DELETIONS* = 2
  SQL_SS_UPDATES* = 4         # SQLColAttributes defines
  SQL_COLUMN_COUNT* = 0
  SQL_COLUMN_NAME* = 1
  SQL_COLUMN_TYPE* = 2
  SQL_COLUMN_LENGTH* = 3
  SQL_COLUMN_PRECISION* = 4
  SQL_COLUMN_SCALE* = 5
  SQL_COLUMN_DISPLAY_SIZE* = 6
  SQL_COLUMN_NULLABLE* = 7
  SQL_COLUMN_UNSIGNED* = 8
  SQL_COLUMN_MONEY* = 9
  SQL_COLUMN_UPDATABLE* = 10
  SQL_COLUMN_AUTO_INCREMENT* = 11
  SQL_COLUMN_CASE_SENSITIVE* = 12
  SQL_COLUMN_SEARCHABLE* = 13
  SQL_COLUMN_TYPE_NAME* = 14
  SQL_COLUMN_TABLE_NAME* = 15
  SQL_COLUMN_OWNER_NAME* = 16
  SQL_COLUMN_QUALIFIER_NAME* = 17
  SQL_COLUMN_LABEL* = 18
  SQL_COLATT_OPT_MAX* = SQL_COLUMN_LABEL
  SQL_COLUMN_DRIVER_START* = 1000
  SQL_DESC_ARRAY_SIZE* = 20
  SQL_DESC_ARRAY_STATUS_PTR* = 21
  SQL_DESC_AUTO_UNIQUE_VALUE* = SQL_COLUMN_AUTO_INCREMENT
  SQL_DESC_BASE_COLUMN_NAME* = 22
  SQL_DESC_BASE_TABLE_NAME* = 23
  SQL_DESC_BIND_OFFSET_PTR* = 24
  SQL_DESC_BIND_TYPE* = 25
  SQL_DESC_CASE_SENSITIVE* = SQL_COLUMN_CASE_SENSITIVE
  SQL_DESC_CATALOG_NAME* = SQL_COLUMN_QUALIFIER_NAME
  SQL_DESC_CONCISE_TYPE* = SQL_COLUMN_TYPE
  SQL_DESC_DATETIME_INTERVAL_PRECISION* = 26
  SQL_DESC_DISPLAY_SIZE* = SQL_COLUMN_DISPLAY_SIZE
  SQL_DESC_FIXED_PREC_SCALE* = SQL_COLUMN_MONEY
  SQL_DESC_LABEL* = SQL_COLUMN_LABEL
  SQL_DESC_LITERAL_PREFIX* = 27
  SQL_DESC_LITERAL_SUFFIX* = 28
  SQL_DESC_LOCAL_TYPE_NAME* = 29
  SQL_DESC_MAXIMUM_SCALE* = 30
  SQL_DESC_MINIMUM_SCALE* = 31
  SQL_DESC_NUM_PREC_RADIX* = 32
  SQL_DESC_PARAMETER_TYPE* = 33
  SQL_DESC_ROWS_PROCESSED_PTR* = 34
  SQL_DESC_SCHEMA_NAME* = SQL_COLUMN_OWNER_NAME
  SQL_DESC_SEARCHABLE* = SQL_COLUMN_SEARCHABLE
  SQL_DESC_TYPE_NAME* = SQL_COLUMN_TYPE_NAME
  SQL_DESC_TABLE_NAME* = SQL_COLUMN_TABLE_NAME
  SQL_DESC_UNSIGNED* = SQL_COLUMN_UNSIGNED
  SQL_DESC_UPDATABLE* = SQL_COLUMN_UPDATABLE #* SQLEndTran() options */
  SQL_COMMIT* = 0
  SQL_ROLLBACK* = 1
  SQL_ATTR_ROW_ARRAY_SIZE* = 27 #* SQLConfigDataSource() options */
  ODBC_ADD_DSN* = 1
  ODBC_CONFIG_DSN* = 2
  ODBC_REMOVE_DSN* = 3
  ODBC_ADD_SYS_DSN* = 4
  ODBC_CONFIG_SYS_DSN* = 5
  ODBC_REMOVE_SYS_DSN* = 6

  SQL_ACTIVE_CONNECTIONS* = 0   # SQLGetInfo
  SQL_DATA_SOURCE_NAME* = 2
  SQL_DATA_SOURCE_READ_ONLY* = 25
  SQL_DATABASE_NAME* = 2
  SQL_DBMS_NAME* = 17
  SQL_DBMS_VERSION* = 18
  SQL_DRIVER_HDBC* = 3
  SQL_DRIVER_HENV* = 4
  SQL_DRIVER_HSTMT* = 5
  SQL_DRIVER_NAME* = 6
  SQL_DRIVER_VER* = 7
  SQL_FETCH_DIRECTION* = 8
  SQL_ODBC_VER* = 10
  SQL_DRIVER_ODBC_VER* = 77
  SQL_SERVER_NAME* = 13
  SQL_ACTIVE_ENVIRONMENTS* = 116
  SQL_ACTIVE_STATEMENTS* = 1
  SQL_SQL_CONFORMANCE* = 118
  SQL_DATETIME_LITERALS* = 119
  SQL_ASYNC_MODE* = 10021
  SQL_BATCH_ROW_COUNT* = 120
  SQL_BATCH_SUPPORT* = 121
  SQL_CATALOG_LOCATION* = 114
  #SQL_CATALOG_NAME* = 10003
  SQL_CATALOG_NAME_SEPARATOR* = 41
  SQL_CATALOG_TERM* = 42
  SQL_CATALOG_USAGE* = 92
  #SQL_COLLATION_SEQ* = 10004
  SQL_COLUMN_ALIAS* = 87
  #SQL_USER_NAME* = 47

proc SQLAllocHandle*(HandleType: TSqlSmallInt, InputHandle: SqlHandle,
                     OutputHandlePtr: var SqlHandle): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLSetEnvAttr*(EnvironmentHandle: SqlHEnv, Attribute: TSqlInteger,
                    Value: TSqlInteger, StringLength: TSqlInteger): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLGetEnvAttr*(EnvironmentHandle: SqlHEnv, Attribute: TSqlInteger,
                    Value: SqlPointer, BufferLength: TSqlInteger,
                    StringLength: PSQLINTEGER): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLFreeHandle*(HandleType: TSqlSmallInt, Handle: SqlHandle): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLGetDiagRec*(HandleType: TSqlSmallInt, Handle: SqlHandle,
                    RecNumber: TSqlSmallInt, Sqlstate: PSQLCHAR,
                    NativeError: var TSqlInteger, MessageText: PSQLCHAR,
                    BufferLength: TSqlSmallInt, TextLength: var TSqlSmallInt): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLGetDiagField*(HandleType: TSqlSmallInt, Handle: SqlHandle,
                      RecNumber: TSqlSmallInt, DiagIdentifier: TSqlSmallInt,
                      DiagInfoPtr: SqlPointer, BufferLength: TSqlSmallInt,
                      StringLengthPtr: var TSqlSmallInt): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLConnect*(ConnectionHandle: SqlHDBC, ServerName: PSQLCHAR,
                 NameLength1: TSqlSmallInt, UserName: PSQLCHAR,
                 NameLength2: TSqlSmallInt, Authentication: PSQLCHAR,
                 NameLength3: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLDisconnect*(ConnectionHandle: SqlHDBC): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLDriverConnect*(hdbc: SqlHDBC, hwnd: SqlHWND, szCsin: cstring,
                       szCLen: TSqlSmallInt, szCsout: cstring,
                       cbCSMax: TSqlSmallInt, cbCsOut: var TSqlSmallInt,
                       f: SqlUSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLBrowseConnect*(hdbc: SqlHDBC, szConnStrIn: PSQLCHAR,
                       cbConnStrIn: TSqlSmallInt, szConnStrOut: PSQLCHAR,
                       cbConnStrOutMax: TSqlSmallInt,
                       cbConnStrOut: var TSqlSmallInt): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLExecDirect*(StatementHandle: SqlHStmt, StatementText: PSQLCHAR,
                    TextLength: TSqlInteger): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLExecDirectW*(StatementHandle: SqlHStmt, StatementText: WideCString,
                    TextLength: TSqlInteger): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLPrepare*(StatementHandle: SqlHStmt, StatementText: PSQLCHAR,
                 TextLength: TSqlInteger): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLPrepareW*(StatementHandle: SqlHStmt, StatementText: WideCString,
                 TextLength: TSqlInteger): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLCloseCursor*(StatementHandle: SqlHStmt): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLExecute*(StatementHandle: SqlHStmt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLFetch*(StatementHandle: SqlHStmt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLNumResultCols*(StatementHandle: SqlHStmt, ColumnCount: var TSqlSmallInt): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLDescribeCol*(StatementHandle: SqlHStmt, ColumnNumber: SqlUSmallInt,
                     ColumnName: PSQLCHAR, BufferLength: TSqlSmallInt,
                     NameLength: var TSqlSmallInt, DataType: var TSqlSmallInt,
                     ColumnSize: var SqlUInteger,
                     DecimalDigits: var TSqlSmallInt, Nullable: var TSqlSmallInt): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLFetchScroll*(StatementHandle: SqlHStmt, FetchOrientation: TSqlSmallInt,
                     FetchOffset: TSqlInteger): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLExtendedFetch*(hstmt: SqlHStmt, fFetchType: SqlUSmallInt,
                       irow: TSqlInteger, pcrow: PSQLUINTEGER,
                       rgfRowStatus: PSQLUSMALLINT): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLGetData*(StatementHandle: SqlHStmt, ColumnNumber: SqlUSmallInt,
                 TargetType: TSqlSmallInt, TargetValue: SqlPointer,
                 BufferLength: TSqlInteger, StrLen_or_Ind: PSQLINTEGER): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLSetStmtAttr*(StatementHandle: SqlHStmt, Attribute: TSqlInteger,
                     Value: SqlPointer, StringLength: TSqlInteger): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLGetStmtAttr*(StatementHandle: SqlHStmt, Attribute: TSqlInteger,
                     Value: SqlPointer, BufferLength: TSqlInteger,
                     StringLength: PSQLINTEGER): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLGetInfo*(ConnectionHandle: SqlHDBC, InfoType: SqlUSmallInt,
                 InfoValue: SqlPointer, BufferLength: TSqlSmallInt,
                 StringLength: PSQLSMALLINT): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLBulkOperations*(StatementHandle: SqlHStmt, Operation: TSqlSmallInt): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLPutData*(StatementHandle: SqlHStmt, Data: SqlPointer,
                 StrLen_or_Ind: TSqlInteger): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLBindCol*(StatementHandle: SqlHStmt, ColumnNumber: SqlUSmallInt,
                 TargetType: TSqlSmallInt, TargetValue: SqlPointer,
                 BufferLength: TSqlInteger, StrLen_or_Ind: PSQLINTEGER): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLSetPos*(hstmt: SqlHStmt, irow: SqlUSmallInt, fOption: SqlUSmallInt,
                fLock: SqlUSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLDataSources*(EnvironmentHandle: SqlHEnv, Direction: SqlUSmallInt,
                     ServerName: PSQLCHAR, BufferLength1: TSqlSmallInt,
                     NameLength1: PSQLSMALLINT, Description: PSQLCHAR,
                     BufferLength2: TSqlSmallInt, NameLength2: PSQLSMALLINT): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLDrivers*(EnvironmentHandle: SqlHEnv, Direction: SqlUSmallInt,
                 DriverDescription: PSQLCHAR, BufferLength1: TSqlSmallInt,
                 DescriptionLength1: PSQLSMALLINT, DriverAttributes: PSQLCHAR,
                 BufferLength2: TSqlSmallInt, AttributesLength2: PSQLSMALLINT): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLSetConnectAttr*(ConnectionHandle: SqlHDBC, Attribute: TSqlInteger,
                        Value: SqlPointer, StringLength: TSqlInteger): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLGetCursorName*(StatementHandle: SqlHStmt, CursorName: PSQLCHAR,
                       BufferLength: TSqlSmallInt, NameLength: PSQLSMALLINT): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLSetCursorName*(StatementHandle: SqlHStmt, CursorName: PSQLCHAR,
                       NameLength: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLRowCount*(StatementHandle: SqlHStmt, RowCount: var TSqlInteger): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLBindParameter*(hstmt: SqlHStmt, ipar: SqlUSmallInt,
                       fParamType: TSqlSmallInt, fCType: TSqlSmallInt,
                       fSqlType: TSqlSmallInt, cbColDef: SqlUInteger,
                       ibScale: TSqlSmallInt, rgbValue: SqlPointer,
                       cbValueMax: TSqlInteger, pcbValue: PSQLINTEGER): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLFreeStmt*(StatementHandle: SqlHStmt, Option: SqlUSmallInt): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLColAttribute*(StatementHandle: SqlHStmt, ColumnNumber: SqlUSmallInt,
                      FieldIdentifier: SqlUSmallInt,
                      CharacterAttribute: PSQLCHAR, BufferLength: TSqlSmallInt,
                      StringLength: PSQLSMALLINT,
                      NumericAttribute: SqlPointer): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLEndTran*(HandleType: TSqlSmallInt, Handle: SqlHandle,
                 CompletionType: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLTables*(hstmt: SqlHStmt, szTableQualifier: PSQLCHAR,
                cbTableQualifier: TSqlSmallInt, szTableOwner: PSQLCHAR,
                cbTableOwner: TSqlSmallInt, szTableName: PSQLCHAR,
                cbTableName: TSqlSmallInt, szTableType: PSQLCHAR,
                cbTableType: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLColumns*(hstmt: SqlHStmt, szTableQualifier: PSQLCHAR,
                 cbTableQualifier: TSqlSmallInt, szTableOwner: PSQLCHAR,
                 cbTableOwner: TSqlSmallInt, szTableName: PSQLCHAR,
                 cbTableName: TSqlSmallInt, szColumnName: PSQLCHAR,
                 cbColumnName: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib, importc.}
proc SQLSpecialColumns*(StatementHandle: SqlHStmt, IdentifierType: SqlUSmallInt,
                        CatalogName: PSQLCHAR, NameLength1: TSqlSmallInt,
                        SchemaName: PSQLCHAR, NameLength2: TSqlSmallInt,
                        TableName: PSQLCHAR, NameLength3: TSqlSmallInt,
                        Scope: SqlUSmallInt,
                        Nullable: SqlUSmallInt): TSqlSmallInt{.
    dynlib: odbclib, importc.}
proc SQLProcedures*(hstmt: SqlHStmt, szTableQualifier: PSQLCHAR,
                    cbTableQualifier: TSqlSmallInt, szTableOwner: PSQLCHAR,
                    cbTableOwner: TSqlSmallInt, szTableName: PSQLCHAR,
                    cbTableName: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLPrimaryKeys*(hstmt: SqlHStmt, CatalogName: PSQLCHAR,
                     NameLength1: TSqlSmallInt, SchemaName: PSQLCHAR,
                     NameLength2: TSqlSmallInt, TableName: PSQLCHAR,
                     NameLength3: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLProcedureColumns*(hstmt: SqlHStmt, CatalogName: PSQLCHAR,
                          NameLength1: TSqlSmallInt, SchemaName: PSQLCHAR,
                          NameLength2: TSqlSmallInt, ProcName: PSQLCHAR,
                          NameLength3: TSqlSmallInt, ColumnName: PSQLCHAR,
                          NameLength4: TSqlSmallInt): TSqlSmallInt{.dynlib: odbclib,
    importc.}
proc SQLStatistics*(hstmt: SqlHStmt, CatalogName: PSQLCHAR,
                    NameLength1: TSqlSmallInt, SchemaName: PSQLCHAR,
                    NameLength2: TSqlSmallInt, TableName: PSQLCHAR,
                    NameLength3: TSqlSmallInt, Unique: SqlUSmallInt,
                    Reserved: SqlUSmallInt): TSqlSmallInt {.
                    dynlib: odbclib, importc.}
proc SQLErr*(henv: SqlHEnv, hdbc: SqlHDBC, hstmt: SqlHStmt,
              szSqlState, pfNativeError, szErrorMsg: PSQLCHAR,
              cbErrorMsgMax: TSqlSmallInt,
              pcbErrorMsg: PSQLSMALLINT): TSqlSmallInt {.
                    dynlib: odbclib, importc: "SQLError".}

{.pop.}