Changeset 14770 in project

05/25/09 00:39:43 (11 years ago)

Add docs for the Chicken 4 port of the Postgresql egg

1 copied


  • wiki/eggref/4/postgresql

    r14757 r14770  
    77=== Description
    9 Simple bindings for [[|PostgreSQL]]'s C-api.
     9Bindings for [[|PostgreSQL]]'s C-api.
    1111=== Author
    2727=== Requirements
    29 * [[easyffi]]
    30 * [[syntax-case]]
    32 === Download
    34 [[|postgresql.egg]]
     29* [[sql-null]]
    3631=== Documentation
    38 This extension provides an interface to the PostgreSQL relational
    39 database.
     33This extension provides an interface to the
     34[[|PostgreSQL]] relational database.
    4136==== Connection functions
    43 <procedure>(pg:connect CONNECTION-SPEC)</procedure>
    45 Opens a connection to the database given in CONNECTION-SPEC,
    46 which should be an alist with entries consisting of a symbol and a
    47 value.  The symbols should be connection keywords recognized by
    48 PostgreSQL's connection function.  See the PostgreSQL documentation
    49 for these.  At the time of writing, they are {{host}},
    50 {{hostaddr}}, {{port}}, {{dbname}},
    51 {{user}}, {{password}}, {{connect_timeout}},
    52 {{options}}, {{sslmode}}, {{service}}.
     38<procedure>(connect CONNECTION-SPEC [TYPE-PARSERS TYPE-UNPARSERS])</procedure>
     40Opens a connection to the database given in CONNECTION-SPEC, which
     41should be either a PostgreSQL connection string or an alist with
     42entries consisting of a symbol and a value (which is internally
     43converted to such a string).  The symbols should be connection
     44keywords recognized by PostgreSQL's connection function.  See the
     45PostgreSQL documentation for these.  At the time of writing, they are
     46{{host}}, {{hostaddr}}, {{port}}, {{dbname}}, {{user}}, {{password}},
     47{{connect_timeout}}, {{options}}, {{sslmode}}, {{service}}.
     49{{TYPE-PARSERS}} is an optional alist that maps PostgreSQL type names
     50to parser procedures, TYPE-UNPARSERS is an optional alist that maps
     51predicates to unparser procedures.  They default to
     52{{(default-type-parsers)}} and {{(default-type-unparsers)}},
     53respectively (see [[#type-conversion|below]]).
    5455The return value is a connection-object.
    5960might not be able to yield because the resolver will block.
    61 <procedure>(pg:close CONNECTION)</procedure>
    63 Closes the given {{CONNECTION}}.
    65 <procedure>(pg:reset CONNECTION)</procedure>
    67 Resets, that is, reopens the connection with the same
    68 connection-specs as was given when opening the original CONNECTION.
    70 <procedure>(pg:connection? OBJECT)</procedure>
     63<procedure>(disconnect CONNECTION)</procedure>
     65Disconnects from the given {{CONNECTION}}.
     67<procedure>(reset-connection CONNECTION)</procedure>
     69Resets, that is, reopens the connection with the same connection-specs
     70as was given when opening the original CONNECTION.
     72<procedure>(connection? OBJECT)</procedure>
    7274Returns true if OBJECT is a PostgreSQL connection-object.
    74 ==== Query functions
    76 For each of the query functions, the query string is a string of one
    77 or more queries to PostgreSQL.  If more than one query is given
    78 (separated by semicolons), the tuples are provided as if a single
    79 query has been executed.  This means that the tuples you get will
    80 possibly not be of the same length.  Tuples are given as vectors.
    82 The values in the tuples are converted to a suitable Scheme
    83 representation, if it is supported.  See [[#conversion|Conversion]].
    85 For queries that don't return tuples, but which return the number of
    86 tuples affected instead, this number is given instead of a vector.
    88 Remember that your QUERY-string might need to be escaped.
    90 <procedure>(pg:query-fold-left QUERY CONNECTION FOLD-FUNCTION . SEEDS)</procedure>
    92 Run FOLD-FUNCTION on each tuple or tuple count returned by the
    93 query (or queries) specified by QUERY until all tuples or tuple
    94 counts have been read, in left to right order, or until the
    95 FOLD-FUNCTION returns {{#f}} as its first return value.
    96 (See the source code for {{pg:query-tuples}} for an
    97 example of how to use this function, and also
    98 [[|SRFI-44]].)
    100 <procedure>(pg:query-for-each PROC QUERY CONNECTION)</procedure>
    102 Runs the QUERY on PostgreSQL CONNECTION, and then maps PROC over each
    103 tuple returned by the query, if any.  The procedure should take one
    104 parameter, in which it is given a tuple.  Returns nothing.
    106 <procedure>(pg:query-tuples QUERY CONNECTION)</procedure>
    108 Returns a list of tuples produced by the database on CONNECTION
    109 as a reply to QUERY.  See also {{pg:query-for-each}}.
    111 <procedure>(pg:sql-null-object? OBJECT)</procedure>
    113 Returns true if OBJECT is an SQL {{NULL}}-value.  Typically used to
    114 check if an element in a tuple is {{NULL}}.
    116 ==== Query functions
    118 <procedure>(pg:escape-string [CONNECTION] STRING)</procedure>
    120 Quotes special characters in {{STRING}} which are otherwise interpreted by the SQL parser.
    121 The {{CONNECTION}} is optional, but ''recommended''.  Not specifying the
    122 connection is ''deprecated''.  It results in a call to {{PQescapeString}},
    123 which is not guaranteed to give a correct response.  Specifying the connection
    124 results in a call to {{PQescapeStringConn}}, which checks the server's
    125 character encoding and other settings.
    127 In future versions of this library, not specifying the connection
    128 will be an error.
     76==== Query procedures
     78<procedure>(query CONN QUERY . PARAMS)</procedure>
     80Execute {{QUERY}}, which is a string containing one SQL statement.
     81{{CONN}} indicates the connection on which to execute the query, and
     82{{PARAMS}} is an arbitrary number of optional arguments indicating
     83positional parameters ({{$1}}, {{$2}} etc).
     85This returns a result object (see below).
     89<init>(use postgresql)</init>
     91(let ((conn (connect '((dbname . test)))))
     92  (row-map identity (query conn "SELECT $1::text, 2::int2" "hello")))
     95(("hello" 2))
     100<procedure>(query* CONN QUERY [PARAMS] [format: FORMAT] [raw: RAW?])</procedure>
     102A less convenient but slightly more powerful version of the {{query}}
     103procedure; {{PARAMS}} must now be a list (instead of rest-arguments).
     104{{FORMAT}} is a symbol specifying how to return the resultset: either
     105as {{binary}} or {{text}} (the default).  {{RAW}} is a boolean which
     106defines whether the {{PARAMS}} should be treated "raw" or first passed
     107through the unparsers associated with {{CONN}}.  If they are treated
     108"raw", they must all be strings, blobs or sql-null objects.
     110See [[#type-conversion|type conversion]] for more info on unparsers.
     114<init>(use postgresql)</init>
     116(let ((conn (connect '((dbname . test)))))
     117  (row-map*
     118    (lambda (a b) (list (blob->string a) (blob->u8vector b)))
     119    (query* conn "SELECT $1::text, 2::int2" '("hello") format: 'binary)))
     122(("hello" #u8(0 2)))
     127<procedure>(multi-query CONN QUERIES)</procedure>
     129A simplified query procedure.  This allows no positional params and no
     130control over how the result is returned (defaulting to text).  The one
     131advantage is that it is allowed to enter multiple SQL statements in
     132the {{QUERIES}} string.  This procedure returns a list of result
     133objects, one for every statement in the string.
     137<init>(use postgresql)</init>
     139(let ((conn (connect '((dbname . test)))))
     140   (map (lambda (r) (row-values r 0))
     141        (multi-query conn "SELECT 'hello', 'world'; SELECT 1")))
     144(("hello" "world") (1))
     149==== High-level API
     151Usually you will use only these procedures to process result sets,
     152but you can fall back to (or even mix with) the low-level API if
     153you need to do custom things.
     155<procedure>(row-fold KONS KNIL RESULT)</procedure>
     156<procedure>(row-fold* KONS KNIL RESULT)</procedure>
     158This is the fundamental fold operator for result sets. It calls
     159{{(kons row seed)}} for every row, where {{row}} is the list of
     160values in the current row and {{seed}} is the accumulated result
     161from previous calls (initially {{knil}}).  It returns the final
     162accumulated result.
     164The starred version works the same, except it calls
     165{{(kons col1 col2 ... seed)}} instead, so the procedure must
     166know how many columns you have in the result set.
     170<init>(use postgresql)</init>
     172(let ((conn (connect '((dbname . test)))))
     173   (row-fold (lambda (row sum) (+ (car row) sum))
     174             0
     175             (query conn "SELECT 1 UNION SELECT 2")))
     182<init>(use postgresql)</init>
     184(let ((conn (connect '((dbname . test)))))
     185   (row-fold* (lambda (value str) (string-append str value))
     186              ""
     187              (query conn "SELECT 'hello, ' UNION SELECT 'world'")))
     190"hello, world"
     194<procedure>(column-fold KONS KNIL RESULT)</procedure>
     195<procedure>(column-fold* KONS KNIL RESULT)</procedure>
     197As {{row-fold}}/{{row-fold*}}, except this iterates sideways through
     198the columns instead of lengthways through the columns, calling
     199{{KONS}} with all values in all the rows of the current column, from
     200left to right.
     202The starred version is much less useful here since you often don't
     203know the number of returned columns, but it is provided for consistency.
     207<init>(use postgresql)</init>
     209(let ((conn (connect '((dbname . test)))))
     210   (column-fold (lambda (col sum) (+ (car col) sum))
     211                0
     212                (query conn "SELECT 1, 100 UNION SELECT 2, 200")))
     220<procedure>(row-for-each PROC RESULT)</procedure>
     221<procedure>(row-for-each* PROC RESULT)</procedure>
     223Simple {{for-each}}, calling the {{(PROC row)}} on each row, in turn,
     224only for the purpose of its side-effects.  The starred version calls
     225{{(PROC col1 col2)}}.
     227<procedure>(column-for-each PROC RESULT)</procedure>
     228<procedure>(column-for-each* PROC RESULT)</procedure>
     230Column variants of {{row-for-each}}/{{row-for-each*}}.
     232<procedure>(row-map PROC RESULT)</procedure>
     233<procedure>(row-map* PROC RESULT)</procedure>
     235Maps rows to lists by applying {{PROC}} to every row and using its
     236result in the result list on the position corresponding to that of the
     237row.  This procedure is not guaranteed to walk the result set in any
     238particular order, so do ''not'' rely on the order {{PROC}} will be
     243<init>(use postgresql)</init>
     245(let ((conn (connect '((dbname . test)))))
     246   (row-map* +
     247             (query conn "SELECT 1, 100 UNION SELECT 2, 200")))
     250(101 202)
     255<procedure>(column-map PROC RESULT)</procedure>
     256<procedure>(column-map* PROC RESULT)</procedure>
     258Column variants of {{row-map}}/{{row-map*}}.
     262<init>(use postgresql)</init>
     264(let ((conn (connect '((dbname . test)))))
     265   (column-map* +
     266                (query conn "SELECT 1, 100 UNION SELECT 2, 200")))
     269(3 300)
     274==== Low-level API
     276<procedure>(result? OBJ)</result>
     278Returns {{#t}} when {{OBJ}} is a result object, {{#f}} otherwise.
     280<procedure>(clear-result! RES)</procedure>
     282Directly clean up all memory used by the result object.  This is
     283normally deferred until garbage collection, but it's made available
     284for when you want more control over when results are released.
     286<procedure>(value-at RES ROW COLUMN [raw: RAW])</procedure>
     288Returns the value at the specified {{ROW}} and {{COLUMN}}.  It is
     289parsed by an appropriate parser unless {{RAW}} is specified and
     290{{#t}}.  If {{RAW}} is true, the value is either a string, blob or an
     291sql-null object.  Otherwise, it depends on the parsers.
     293See [[#type-conversion|type conversion]] for more info on parsers.
     295<procedure>(row-values RES ROW [raw: RAW])</procedure>
     297Returns a list of all the columns' values at the given {{ROW}} number.
     299<procedure>(column-values RES ROW [raw: RAW])</procedure>
     301Returns a list of all the rows' values at the given {{COLUMN}} number.
     303<procedure>(row-alist RES ROW)</procedure>
     305Returns an alist of the values at the given {{ROW}} number.  The keys
     306of the alist are made up by the matching column names, as symbols.
     308<procedure>(affected-rows RES)</procedure>
     310For INSERT or UPDATE statements, this returns the number of rows
     311affected by the statement that RES is a result for.  Otherwise it's
     314<procedure>(inserted-oid RES)</procedure>
     316For INSERT statements resulting in a single record being inserted,
     317this returns the OID (a number) assigned to the newly inserted row.
     318Returns {{#f}} for non-INSERT or multi-row INSERTs, or INSERTs into
     319tables without OIDs.
     321<procedure>(row-count RES)</procedure>
     323Returns the number of rows in the result set.
     325<procedure>(column-count RES)</procedure>
     327Returns the number of columns in the result set.
     329<procedure>(column-index RES COLUMN)</procedure>
     331Returns the index of {{COLUMN}} in the result set. {{COLUMN}} should
     332be a symbol indicating the column name.
     334<procedure>(column-name RES INDEX)</procedure>
     336Returns the name of the column (a symbol) at the position in the
     337result set specified by {{INDEX}}.  This is its aliased name in the
     338result set.
     340<procedure>(column-names RES)</procedure>
     342Returns a list of all the column names (symbols) in the result set.
     343The position in the list reflects the position of the column in the
     344result set.
     346<procedure>(column-format RES INDEX)</procedure>
     348Returns the format of the column at {{INDEX}}, which is a symbol;
     349Either {{text}} or {{binary}}.  This determines whether the value
     350returned by {{value-at}} will be a string or a blob.
     352<procedure>(column-type RES INDEX)</procedure>
     354Returns the OID (an integer) of the column at {{INDEX}}.
     356<procedure>(column-type-modifier RES INDEX)</procedure>
     358Returns an type-specific modifier (a number), or {{#f}} if the type
     359has no modifier.
     361<procedure>(table-oid RES INDEX)</procedure>
     363The OID (a number) of the table from whence the result column at
     364{{INDEX}} originated, or {{#f}} if the column is not a simple
     365reference to a table column.
     367<procedure>(table-column-index RES INDEX)</procedure>
     369Returns the column number (within its table) of the column making up
     370the query result column at the position specified by {{INDEX}}.
     372'''Note:''' This procedure returns indexes starting at zero, as one
     373would expect.  However, the underlying C function {{PQftablecol}} is
     374one-based.  This might trip up experienced Postgres hackers.
     377==== Value escaping
     379To embed arbitrary values in query strings, you must escape them
     380first, to protect yourself from SQL injection bugs.  This is not
     381required if you use positional arguments (the {{PARAMS}} arguments
     382in the {{query}} procedures).
     384<procedure>(escape-string CONNECTION STRING)</procedure>
     386Quotes special characters in {{STRING}} which are otherwise
     387interpreted by the SQL parser, obeying the {{CONNECTION}}'s encoding
     390<procedure>(escape-bytea CONNECTION STRING)</procedure>
     392Quotes special characters in {{STRING}} which are otherwise
     393interpreted by the SQL parser.  This differs from {{escape-string}} in
     394that some bytes are doubly encoded so they can be used for bytea
     397This is required because of a technicality; PostgreSQL first parses
     398the string value as a string, and then casts this string to bytea,
     399interpreting another layer of escape codes.
     401For example, {{E'a\\000bcd'}} is first converted to {{'a\000bcd'}} by
     402the text parser, and then interpreted by the bytea parser as an "a"
     403followed by a NUL byte, followed by "bcd".  In Scheme, the value
     404returned by {{(escape-bytea conn "a\x00bcd")}} is {{"a\\\\000bcd"}}.
     405Yes, that's a lot of backslashes :)
     407<procedure>(unescape-bytea STRING)</procedure>
     409This unescapes a bytea '''result''' from the server.  It is '''not the
     410inverse of {{escape-bytea}}''', because string values returned by the
     411server are not escaped for the text-parser. (ie, step one in the encoding
     412process described under {{escape-bytea}} is skipped)
    130414==== Constants
    132 <constant>(sql-null-object)</constant>
    134 Represents SQL {{NULL}} values.
     418Represents the numeric value of the invalid Oid.  Rarely useful,
     419except perhaps when doing low-level operations in the system catalog.
    136421==== Error handling
    138423  condition: postgresql
    140 A condition of kind (exn postgresql) is
    141 signaled when an error occurs.  The postgresql component of this condition contains
    142 several properties.  Unless otherwise noted, these properties
    143 may not be present, in which case they have the value {{#f}}.
     425A condition of kind (exn postgresql) is signaled when an error occurs.
     426The postgresql component of this condition contains several
     427properties.  Unless otherwise noted, these properties may not be
     428present, in which case they have the value {{#f}}.
    145430; {{severity}} : One of the symbols {{error}}, {{fatal}}, {{panic}}, {{warning}},  {{notice}}, {{debug}}, {{info}}, {{log}}. Always present.
    146 ; {{error-class}} : a symbol representating a Postgresql error class. 
    147 ; {{error-code}} :  A symbol representing a Postgresql error code.  See the [[|Postgresql documentation]] for a description of error codes and error classes.  They are mapped in an obvious way to Scheme symbols.  See source for details.
     431; {{error-class}} : A string representating a Postgresql error class (the first two characters of {{error-code}}).
     432; {{error-code}} :  A string representing a Postgresql error code.  See the [[|Postgresql documentation]] for a description of error codes and error classes.
    148433; {{message-detail}} :  A secondary (to the usual {{exn message}} property) message with extra detail about the problem.
    149434; {{message-hint}} :  A string with a suggestion about what to do about the problem.
    154439; {{source-function}} :  The name of the source-code function reporting the error.
    156 ==== Conversion
    158 Type information is read from the database the first time you
    159 connect to it.  Note that ISO-style dates are assumed, so please set
    160 PostgreSQL up to use this.  Here is an overview of how the mapping
    161 is done currently:
    163 <table>
    164 <tr>
    165 <th>PostgreSQL type</th>
    166 <th>Scheme type</th>
    167 </tr>
    168 <tr><td>TEXT</td><td>string</td></tr>
    169 <tr><td>BYTEA</td><td>string</td></tr>
    170 <tr><td>CHAR</td><td>char</td></tr>
    171 <tr><td>BPCHAR</td><td>char</td></tr>
    172 <tr><td>BOOL</td><td>boolean</td></tr>
    173 <tr><td>INT8</td><td>fixnum or inexact<nowiki><sup>1</sup></nowiki></td></tr>
    174 <tr><td>INT4</td><td>fixnum or inexact<nowiki><sup>1</sup></nowiki></td></tr>
    175 <tr><td>INT2</td><td>fixnum</td></tr>
    176 <tr><td>FLOAT8</td><td>inexact</td></tr>
    177 <tr><td>FLOAT4</td><td>inexact</td></tr>
    178 <tr><td>ABSTIME</td><td>unsupported<nowiki><sup>2</sup></nowiki></td></tr>
    179 <tr><td>RELTIME</td><td>unsupported<nowiki><sup>2</sup></nowiki></td></tr>
    180 <tr><td>DATE</td><td>vector {{#(year month date)}}</td></tr>
    181 <tr><td>TIME</td><td>vector {{#(hour minute second microsecond)}}</td></tr>
    182 <tr>
    183 <td>TIMESTAMP</td>
    184 <td>vector {{#(year month date hour minute second microsecond)}}</td>
    185 </tr>
    186 <tr>
    187 <td>TIMESTAMPTZ</td>
    188 <td>vector {{#(year month date hour minute second microsecond timezone)}}</td>
    189 </tr>
    190 <tr><td>INTERVAL</td><td>unsupported<nowiki><sup>2</sup></nowiki></td></tr>
    191 <tr><td>NUMERIC</td><td>fixnum or inexact<nowiki><sup>1</sup></nowiki></td></tr>
    192 <tr><td>OID</td><td>fixnum or inexact<nowiki><sup>1</sup></nowiki></td></tr>
    193 </table>
    196 1. This means you will get a fixnum if the number is small enough, and a floating point number otherwise.  If it's too large to be represented as a floating point number, an error is signaled.
    198 2. These are just returned as text for now.
    200 === Example
    202 <examples><example>
    203 <expr>
    204 (let ([conn (pg:connect '((dbname . "johs")))])
    205   (pg:query-for-each
    206    (lambda (tuple)
    207      (do [(i 0 (+ i 1))]
    208          [(= i (vector-length tuple))]
    209        (let ([element (vector-ref tuple i)])
    210          (format #t "~15S" (if (pg:sql-null-object? element)
    211                                "NULL"
    212                                element))))
    213      (newline))
    214    "SELECT * FROM foo LIMIT 5"
    215    conn)
    216   (pg:close conn))
    217 </expr>
    218 </example></examples>
     441==== Type conversion
     443Type information is read from the database the first time you connect
     444to it.  Result set values are either text or binary (or sql null).  If
     445they are text, they are converted to Scheme objects by type parsers,
     446as described below.  If they are binary, they will be returned as
     447unprocessed blobs (which you can then convert to u8vectors or strings).
     449===== Parsers
     451<parameter>(default-type-parsers [ALIST])</parameter>
     453Postgres result values are always just strings, but it is possible to
     454map these to real Scheme objects.  With this parameter, you can
     455map your own custom postgresql datatype to Scheme datatypes.
     457The alist is a mapping of Postgres type names (strings) to procedures
     458accepting a string and returning a Scheme object of the desired type.
     460The parsers can also be set per connection with the {{TYPE-PARSERS}}
     461argument of the {{connect}} procedure.
     465<init>(use postgresql)</init>
     467(parameterize ((default-type-parsers `(("text" . ,string->symbol))))
     468  (let ((conn (connect '((dbname . test)))))
     469    (row-map identity (query conn "SELECT 'hello'::text"))))
     477The default parsers look like this:
     479<enscript highlight=scheme>
     480`(("text" . ,identity)
     481  ("bytea" . ,bytea-parser)
     482  ("char" . ,char-parser)
     483  ("bpchar" . ,identity)
     484  ("bool" . ,bool-parser)
     485  ("int8" . ,numeric-parser)
     486  ("int4" . ,numeric-parser)
     487  ("int2" . ,numeric-parser)
     488  ("float4" . ,numeric-parser)
     489  ("float8" . ,numeric-parser)
     490  ("numeric" . ,numeric-parser)
     491  ("oid" . ,numeric-parser))
     494These parsers are described below.  For anything where no parser is
     495found, the value is returned verbatim (which is always a string, or a
     496blob in case of binary data).
     498<procedure>(update-type-parsers! CONN [TYPE-PARSERS])</procedure>
     500As described above, type information is extracted from the system
     501catalog whenever you initiate a new connection.  However, there is a
     502bootstrapping problem when you are defining custom data types.  You
     503must first connect before you can define your custom data types.  But
     504the type parsers do not have the information for this new type yet, so
     505you must update them.
     507To do this, you can call {{update-type-parsers!}}.  This procedure
     508updates all the type parsers originally associated with connection
     509{{CONN}}.  By providing the optional {{TYPE-PARSERS}}, you can
     510override the existing type parsers for this connection with new ones,
     511otherwise the old ones are just refreshed.
     513<procedure>(bool-parser STR)</procedure>
     515Returns {{#t}} if the string equals {{"t"}}, {{#f}} otherwise.
     517<procedure>(bytea-parser STR)</procedure>
     519Returns a u8vector containing the bytes in STR, after unescaping it
     520using {{unescape-bytea}}.
     522<procedure>(char-parser STR)</procedure>
     524Returns the first character in STR.
     526<procedure>(numeric-parser STR)</procedure>
     528Returns {{STR}} converted to a number using decimal representation.
     529If {{STR}} could not be converted to a number, raises an error.
     531===== Unparsers
     533<parameter>(default-type-unparsers [ALIST])</parameter>
     535Just as PostgreSQL types are converted to Scheme types in result sets,
     536Scheme types need to be converted to PostgreSQL types when providing
     537positional parameters to queries.  For this, the library uses type
     538unparsers.  Just like type parsers, you can override them either
     539per-connection using the {{TYPE-UNPARSERS}} parameter to the
     540{{connect}} procedure, or globally by changing a parameter.
     542This alist is a mapping of predicates to unparsers.  Predicates are
     543procedures which accept a scheme object and return a true value if the
     544object is of the type for which the unparser is intended.  Unparsers
     545are procedures which accept a scheme object and return either a
     546string, a blob or an sql-null object to be used in the query.
     548It is not necessary to reload type unparsers after defining a new data
     549type in the database.
     551Order matters; the type unparser alist is traversed from left to
     552right, trying predicates in order and invoking the unparser linked to
     553the first predicate that does not return {{#f}}.  If none of the
     554predicates match, the type must be of string, blob or sql-null type.
     555If not, the query procedure will raise an error.
     557The default unparsers look like this:
     559<enscript highlight=scheme>
     560`((,string? . ,identity)
     561  (,u8vector? . ,u8vector->blob/shared)
     562  (,char? . ,string)
     563  (,boolean? . ,bool-unparser)
     564  (,number? . ,number->string))
     567<procedure>(bool-unparser B)</procedure>
     569Returns {{"TRUE"}} for true values and {{"FALSE"}} for {{#f}}.
    220571=== Changelog
    222 * trunk - Add PQescapeStringConn functionality to pg:escape-string. Fixed weird compilation issue with SRFI-69 by removing it from USES list.
     573* 3.0 - Port to Chicken 4.  Major code overhaul, backwards incompatible.
     574* 2.0.14 - Add PQescapeStringConn functionality to pg:escape-string. Fixed weird compilation issue with SRFI-69 by removing it from USES list.
    223575* 2.0.12 - added {{pg:named-tuples}} parameter [Contributed by Graham Fawcett]
    224576* 2.0.11 - added syntax-case requirements to .meta file [Thanks to Michele Simionato]
    237589=== License
     591  Copyright (C) 2008-2009 Peter Bex
    239592  Copyright (C) 2004 Johannes GrÞdem <>
    240593  Redistribution and use in source and binary forms, with or without
Note: See TracChangeset for help on using the changeset viewer.