Red [
    Title:      "SQLite Binding"
    Author:     "Kaj de Vos"
    Rights:     "Copyright (c) 2011,2012 Kaj de Vos. All rights reserved."
    License: {
        Redistribution and use in source and binary forms, with or without modification,
        are permitted provided that the following conditions are met:

            * Redistributions of source code must retain the above copyright notice,
              this list of conditions and the following disclaimer.
            * Redistributions in binary form must reproduce the above copyright notice,
              this list of conditions and the following disclaimer in the documentation
              and/or other materials provided with the distribution.

        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
        ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
        FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
        OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    }
    Needs: {
        Red > 0.3.1
        SQLite 3
    }
    Tabs:       4
]


#system-global [
;   #include %../SQLite.reds
    #include %/home/kaj/Desktop/Red/SQLite/SQLite.reds  ; FIXME: #252
]


; Data types

sqlite-integer!:            1
sqlite-float!:              2
sqlite-string!:             3
sqlite-binary!:             4
sqlite-none!:               5


; Memory management

memory-static:              0
memory-transient:           -1


; Error handling

status-ok:                  0

error-sql:                  1
error-internal:             2
error-permission:           3
error-abort:                4
error-busy:                 5
error-locked:               6
error-memory:               7
error-read-only:            8
error-interrupt:            9
error-input-output:         10
error-corrupt:              11
error-not-found:            12
error-full:                 13
error-opening:              14
error-protocol:             15
error-empty:                16
error-schema:               17
error-too-big:              18
error-constraint:           19
error-mismatch:             20
error-misuse:               21
error-no-lfs:               22
error-authorization:        23
error-format:               24
error-range:                25
error-no-db:                26

status-next-row:            100
status-done:                101


; Open VFS masks

open-read-only:             00000001h
open-read-write:            00000002h
open-create:                00000004h
open-delete-on-close:       00000008h
open-exclusive:             00000010h
open-auto-proxy:            00000020h
open-uri:                   00000040h
open-main-db:               00000100h
open-temporary-db:          00000200h
open-transient-db:          00000400h
open-main-journal:          00000800h
open-temporary-journal:     00001000h
open-subjournal:            00002000h
open-master-journal:        00004000h
open-no-mutex:              00008000h
open-full-mutex:            00010000h
open-shared-cache:          00020000h
open-private-cache:         00040000h
open-wal:                   00080000h


version: routine [  ; Return SQLite version.
    return:             [integer!]  ; c-string!
][
    as-integer sqlite/version
]
source-version: routine [  ; Return SQLite source ID.
    return:             [integer!]  ; c-string!
][
    as-integer sqlite/source-version
]
version-number: routine [  ; Return SQLite version number.
    return:             [integer!]
][
    sqlite/version-number
]


; Error handling

status-of: routine [  ; Return status code.
    db                  [integer!]  ; sqlite!
    return:             [integer!]  ; status!
][
    sqlite/status-of as sqlite! db
]
extended-error-of: routine [  ; Return extended status code.
    db                  [integer!]  ; sqlite!
    return:             [integer!]
][
    sqlite/extended-error-of as sqlite! db
]
form-error: routine [  ; Return UTF-8 status message.
    db                  [integer!]  ; sqlite!
    return:             [integer!]  ; c-string!
][
    as-integer sqlite/form-error as sqlite! db
]
form-error-utf16: routine [  ; Return UTF-16 status message.
    db                  [integer!]  ; sqlite!
    return:             [integer!]  ; binary!
][
    as-integer sqlite/form-error-utf16 as sqlite! db
]


; Global setup and teardown

begin-sqlite: routine [  ; Initialise global environment.
    return:             [integer!]  ; status!
][
    sqlite/begin-sqlite
]
end-sqlite: routine [  ; Clean up global environment.
    return:             [integer!]  ; status!
][
    sqlite/end-sqlite
]


; Memory management

sqlite-allocate: routine [  ; Allocate memory.
    size                [integer!]
    return:             [integer!]  ; binary!
][
    as-integer sqlite/sqlite-allocate size
]
sqlite-resize: routine [  ; Resize memory allocation.
    memory              [integer!]  ; binary!
    size                [integer!]
    return:             [integer!]  ; binary!
][
    as-integer sqlite/sqlite-resize as-binary memory  size
]
sqlite-free: routine [  ; Free allocated memory.
    memory              [integer!]  ; binary!
][
    sqlite/sqlite-free as-binary memory
]


; Database management

open-database: routine [  ; Open a UTF-8 database file.
    file                [integer!]  ; c-string!
    db-reference        [integer!]  ; sqlite-reference!
    return:             [integer!]  ; status!
][
    sqlite/open-database as-c-string file  as sqlite-reference! db-reference
]
open-utf16: routine [  ; Open a UTF-16 database file.
    file                [integer!]  ; binary!
    db-reference        [integer!]  ; sqlite-reference!
    return:             [integer!]  ; status!
][
    sqlite/open-utf16 as-binary file  as sqlite-reference! db-reference
]
open-vfs: routine [  ; Open a UTF-8 database file via VFS.
    file                [integer!]  ; c-string!
    db-reference        [integer!]  ; sqlite-reference!
    flags               [integer!]  ; open-mask!
    vfs                 [integer!]  ; c-string!
    return:             [integer!]  ; status!
][
    sqlite/open-vfs as-c-string file  as sqlite-reference! db-reference  flags as-c-string vfs
]

close-database: routine [  ; Close database.
    db                  [integer!]  ; sqlite!
    return:             [integer!]  ; status!
][
    sqlite/close-database as sqlite! db
]


; SQL processing

do: routine [  ; Execute SQL statements.
    db                  [integer!]  ; sqlite!
    sql                 [integer!]  ; c-string!
;   row-handler         [function! [
;                           data    [handle!]
;                           columns [integer!]
;                           values  [string-reference!]
;                           names   [string-reference!]
;                           return: [sql-status!]
;                       ]]  ; Callback, or NULL
    row-handler         [integer!]
    data                [integer!]  ; handle!
    error-reference     [integer!]  ; string-reference!, message pointer, or NULL
    return:             [integer!]  ; status!
][
    sqlite/do as sqlite! db  as-c-string sql  row-handler as-handle data  as string-reference! error-reference
]

load-next: routine [  ; Compile a UTF-8 SQL statement.
    db                  [integer!]  ; sqlite!
    sql                 [integer!]  ; c-string!
    size                [integer!]  ; Negative: null-terminated
    statement           [integer!]  ; sql-reference!
    tail                [integer!]  ; string-reference!, progress pointer, or NULL
    return:             [integer!]  ; status!
][
    sqlite/load-next as sqlite! db  as-c-string sql  size as sql-reference! statement  as string-reference! tail
]
load-next-utf16: routine [  ; Compile a UTF-16 SQL statement.
    db                  [integer!]  ; sqlite!
    sql                 [integer!]  ; binary!
    size                [integer!]  ; Negative: null-terminated
    statement           [integer!]  ; sql-reference!
    tail                [integer!]  ; binary-reference!, progress pointer, or NULL
    return:             [integer!]  ; status!
][
    sqlite/load-next-utf16 as sqlite! db  as-binary sql  size as sql-reference! statement  as binary-reference! tail
]
end-sql: routine [  ; Clean up SQL statement.
    sql                 [integer!]  ; sql!
    return:             [integer!]  ; status!
][
    sqlite/end-sql as sql! sql
]

do-next: routine [  ; Execute SQL statement.
    sql                 [integer!]  ; sql!
    return:             [integer!]  ; status!
][
    sqlite/do-next as sql! sql
]
clear-sql: routine [  ; Reset SQL statement for next evaluation.
    sql                 [integer!]  ; sql!
    return:             [integer!]  ; status!
][
    sqlite/clear-sql as sql! sql
]


; Binding

unbind: routine [  ; Clear bindings to SQL statement.
    sql                 [integer!]  ; sql!
    return:             [integer!]  ; status!
][
    sqlite/unbind as sql! sql
]


count-parameters: routine [  ; Highest parameter index in SQL statement.
    sql                 [integer!]  ; sql!
    return:             [integer!]
][
    sqlite/count-parameters as sql! sql
]
find-parameter: routine [  ; Index of parameter within SQL statement.
    sql                 [integer!]  ; sql!
    name                [integer!]  ; c-string!
    return:             [integer!]  ; 0: no match
][
    sqlite/find-parameter as sql! sql  as-c-string name
]
pick-symbol: routine [  ; Name of parameter in SQL statement.
    sql                 [integer!]  ; sql!
    index               [integer!]
    return:             [integer!]  ; c-string!, NULL: no match
][
    as-integer sqlite/pick-symbol as sql! sql  index
]


bind-none: routine [  ; Bind to NULL.
    sql                 [integer!]  ; sql!
    index               [integer!]  ; 1 based
    return:             [integer!]  ; status!
][
    sqlite/bind-none as sql! sql  index
]
bind-zero: routine [  ; Bind zero-filled binary value.
    sql                 [integer!]  ; sql!
    index               [integer!]
    size                [integer!]
    return:             [integer!]  ; status!
][
    sqlite/bind-zero as sql! sql  index size
]

bind: routine [  ; Bind dynamic value.
    sql                 [integer!]  ; sql!
    index               [integer!]
    value               [integer!]  ; value!
    return:             [integer!]  ; status!
][
    sqlite/bind as sql! sql  index as value! value
]

bind-integer: routine [  ; Bind integer.
    sql                 [integer!]  ; sql!
    index               [integer!]
    value               [integer!]
    return:             [integer!]  ; status!
][
    sqlite/bind-integer as sql! sql  index value
]
;bind-integer64: routine [  ; Bind 64-bits integer.
;   sql                 [integer!]  ; sql!
;   index               [integer!]
;   value               [integer64!]
;   return:             [integer!]  ; status!
;][
;   sqlite/bind-integer64 as sql! sql  index value
;]
;bind-float: routine [  ; Bind floating point value.
;   sql                 [integer!]  ; sql!
;   index               [integer!]
;   value               [float!]
;   return:             [integer!]  ; status!
;][
;   sqlite/bind-float as sql! sql  index value
;]
bind-binary: routine [  ; Bind binary value.
    sql                 [integer!]  ; sql!
    index               [integer!]
    value               [integer!]  ; binary!
    size                [integer!]  ; Negative: null-terminated
;   free                [function! [value [binary!]]]
    free                [integer!]
    return:             [integer!]  ; status!
][
    sqlite/bind-binary as sql! sql  index as-binary value  size free
]
bind-string: routine [  ; Bind text.
    sql                 [integer!]  ; sql!
    index               [integer!]
    value               [integer!]  ; c-string!
    size                [integer!]  ; Negative: null-terminated
;   free                [function! [value [binary!]]]
    free                [integer!]
    return:             [integer!]  ; status!
][
    sqlite/bind-string as sql! sql  index as-c-string value  size free
]
bind-utf16: routine [  ; Bind UTF-16 text.
    sql                 [integer!]  ; sql!
    index               [integer!]
    value               [integer!]  ; binary!
    size                [integer!]  ; Negative: null-terminated
;   free                [function! [value [binary!]]]
    free                [integer!]
    return:             [integer!]  ; status!
][
    sqlite/bind-utf16 as sql! sql  index as-binary value  size free
]


; Result row processing

count-columns: routine [  ; Number of columns in the result row.
    row                 [integer!]  ; sql!
    return:             [integer!]
][
    sqlite/count-columns as sql! row
]

pick-size: routine [  ; Column value size in bytes.
    row                 [integer!]  ; sql!
    column              [integer!]  ; 0 based
    return:             [integer!]
][
    sqlite/pick-size as sql! row  column
]
pick-utf16-size: routine [  ; UTF-16 column value size in bytes.
    row                 [integer!]  ; sql!
    column              [integer!]
    return:             [integer!]
][
    sqlite/pick-utf16-size as sql! row  column
]

pick-name: routine [  ; Column name.
    row                 [integer!]  ; sql!
    column              [integer!]
    return:             [integer!]  ; c-string!
][
    as-integer sqlite/pick-name as sql! row  column
]
pick-utf16-name: routine [  ; UTF-16 column name.
    row                 [integer!]  ; sql!
    column              [integer!]
    return:             [integer!]  ; binary!
][
    as-integer sqlite/pick-utf16-name as sql! row  column
]

pick-type: routine [  ; Column type.
    row                 [integer!]  ; sql!
    column              [integer!]
    return:             [integer!]  ; type!
][
    sqlite/pick-type as sql! row  column
]
pick: routine [  ; Extract dynamic column value.
    row                 [integer!]  ; sql!
    column              [integer!]
    return:             [integer!]  ; value!
][
    as-integer sqlite/pick as sql! row  column
]

pick-integer: routine [  ; Extract integer column value.
    row                 [integer!]  ; sql!
    column              [integer!]
    return:             [integer!]
][
    sqlite/pick-integer as sql! row  column
]
;pick-integer64: routine [  ; Extract 64-bits integer column value.
;   row                 [integer!]  ; sql!
;   column              [integer!]
;   return:             [integer64!]
;][
;   sqlite/pick-integer64 as sql! row  column
;]
;pick-float: routine [  ; Extract floating point column value.
;   row                 [integer!]  ; sql!
;   column              [integer!]
;   return:             [float!]
;][
;   sqlite/pick-float as sql! row  column
;]
pick-binary: routine [  ; Extract binary column value.
    row                 [integer!]  ; sql!
    column              [integer!]
    return:             [integer!]  ; binary!
][
    as-integer sqlite/pick-binary as sql! row  column
]
pick-string: routine [  ; Extract column text.
    row                 [integer!]  ; sql!
    column              [integer!]
    return:             [integer!]  ; c-string!
][
    as-integer sqlite/pick-string as sql! row  column
]
pick-utf16: routine [  ; Extract UTF-16 column value.
    row                 [integer!]  ; sql!
    column              [integer!]
    return:             [integer!]  ; binary!
][
    as-integer sqlite/pick-utf16 as sql! row  column
]