Changeset 14770 in project


Ignore:
Timestamp:
05/25/09 00:39:43 (10 years ago)
Author:
sjamaan
Message:

Add docs for the Chicken 4 port of the Postgresql egg

File:
1 copied

Legend:

Unmodified
Added
Removed
  • wiki/eggref/4/postgresql

    r14757 r14770  
    77=== Description
    88
    9 Simple bindings for [[http://www.postgresql.org/|PostgreSQL]]'s C-api.
     9Bindings for [[http://www.postgresql.org/|PostgreSQL]]'s C-api.
    1010
    1111=== Author
     
    2727=== Requirements
    2828
    29 * [[easyffi]]
    30 * [[syntax-case]]
    31 
    32 === Download
    33 
    34 [[http://www.call-with-current-continuation.org/eggs/postgresql.egg|postgresql.egg]]
     29* [[sql-null]]
    3530
    3631=== Documentation
    3732
    38 This extension provides an interface to the PostgreSQL relational
    39 database.
     33This extension provides an interface to the
     34[[http://www.postgresql.org|PostgreSQL]] relational database.
    4035
    4136==== Connection functions
    4237
    43 <procedure>(pg:connect CONNECTION-SPEC)</procedure>
    44 
    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>
     39
     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}}.
     48
     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]]).
    5354
    5455The return value is a connection-object.
     
    5960might not be able to yield because the resolver will block.
    6061
    61 <procedure>(pg:close CONNECTION)</procedure>
    62 
    63 Closes the given {{CONNECTION}}.
    64 
    65 <procedure>(pg:reset CONNECTION)</procedure>
    66 
    67 Resets, that is, reopens the connection with the same
    68 connection-specs as was given when opening the original CONNECTION.
    69 
    70 <procedure>(pg:connection? OBJECT)</procedure>
     62
     63<procedure>(disconnect CONNECTION)</procedure>
     64
     65Disconnects from the given {{CONNECTION}}.
     66
     67<procedure>(reset-connection CONNECTION)</procedure>
     68
     69Resets, that is, reopens the connection with the same connection-specs
     70as was given when opening the original CONNECTION.
     71
     72<procedure>(connection? OBJECT)</procedure>
    7173
    7274Returns true if OBJECT is a PostgreSQL connection-object.
    7375
    74 ==== Query functions
    75 
    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.
    81 
    82 The values in the tuples are converted to a suitable Scheme
    83 representation, if it is supported.  See [[#conversion|Conversion]].
    84 
    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.
    87 
    88 Remember that your QUERY-string might need to be escaped.
    89 
    90 <procedure>(pg:query-fold-left QUERY CONNECTION FOLD-FUNCTION . SEEDS)</procedure>
    91 
    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 [[http://srfi.schemers.org/srfi-44/|SRFI-44]].)
    99 
    100 <procedure>(pg:query-for-each PROC QUERY CONNECTION)</procedure>
    101 
    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.
    105 
    106 <procedure>(pg:query-tuples QUERY CONNECTION)</procedure>
    107 
    108 Returns a list of tuples produced by the database on CONNECTION
    109 as a reply to QUERY.  See also {{pg:query-for-each}}.
    110 
    111 <procedure>(pg:sql-null-object? OBJECT)</procedure>
    112 
    113 Returns true if OBJECT is an SQL {{NULL}}-value.  Typically used to
    114 check if an element in a tuple is {{NULL}}.
    115 
    116 ==== Query functions
    117 
    118 <procedure>(pg:escape-string [CONNECTION] STRING)</procedure>
    119 
    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.
    126 
    127 In future versions of this library, not specifying the connection
    128 will be an error.
     76==== Query procedures
     77
     78<procedure>(query CONN QUERY . PARAMS)</procedure>
     79
     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).
     84
     85This returns a result object (see below).
     86
     87<examples>
     88<example>
     89<init>(use postgresql)</init>
     90<expr>
     91(let ((conn (connect '((dbname . test)))))
     92  (row-map identity (query conn "SELECT $1::text, 2::int2" "hello")))
     93</expr>
     94<result>
     95(("hello" 2))
     96</result>
     97</example>
     98</example>
     99
     100<procedure>(query* CONN QUERY [PARAMS] [format: FORMAT] [raw: RAW?])</procedure>
     101
     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.
     109
     110See [[#type-conversion|type conversion]] for more info on unparsers.
     111
     112<examples>
     113<example>
     114<init>(use postgresql)</init>
     115<expr>
     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)))
     120</expr>
     121<result>
     122(("hello" #u8(0 2)))
     123</result>
     124</example>
     125</example>
     126
     127<procedure>(multi-query CONN QUERIES)</procedure>
     128
     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.
     134
     135<examples>
     136<example>
     137<init>(use postgresql)</init>
     138<expr>
     139(let ((conn (connect '((dbname . test)))))
     140   (map (lambda (r) (row-values r 0))
     141        (multi-query conn "SELECT 'hello', 'world'; SELECT 1")))
     142</expr>
     143<result>
     144(("hello" "world") (1))
     145</result>
     146</example>
     147</example>
     148
     149==== High-level API
     150
     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.
     154
     155<procedure>(row-fold KONS KNIL RESULT)</procedure>
     156<procedure>(row-fold* KONS KNIL RESULT)</procedure>
     157
     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.
     163
     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.
     167
     168<examples>
     169<example>
     170<init>(use postgresql)</init>
     171<expr>
     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")))
     176</expr>
     177<result>
     1783
     179</result>
     180</example>
     181<example>
     182<init>(use postgresql)</init>
     183<expr>
     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'")))
     188</expr>
     189<result>
     190"hello, world"
     191</result>
     192</example>
     193
     194<procedure>(column-fold KONS KNIL RESULT)</procedure>
     195<procedure>(column-fold* KONS KNIL RESULT)</procedure>
     196
     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.
     201
     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.
     204
     205<examples>
     206<example>
     207<init>(use postgresql)</init>
     208<expr>
     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")))
     213</expr>
     214<result>
     215101
     216</result>
     217</example>
     218</examples>
     219
     220<procedure>(row-for-each PROC RESULT)</procedure>
     221<procedure>(row-for-each* PROC RESULT)</procedure>
     222
     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)}}.
     226
     227<procedure>(column-for-each PROC RESULT)</procedure>
     228<procedure>(column-for-each* PROC RESULT)</procedure>
     229
     230Column variants of {{row-for-each}}/{{row-for-each*}}.
     231
     232<procedure>(row-map PROC RESULT)</procedure>
     233<procedure>(row-map* PROC RESULT)</procedure>
     234
     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
     239called.
     240
     241<examples>
     242<example>
     243<init>(use postgresql)</init>
     244<expr>
     245(let ((conn (connect '((dbname . test)))))
     246   (row-map* +
     247             (query conn "SELECT 1, 100 UNION SELECT 2, 200")))
     248</expr>
     249<result>
     250(101 202)
     251</result>
     252</example>
     253</examples>
     254
     255<procedure>(column-map PROC RESULT)</procedure>
     256<procedure>(column-map* PROC RESULT)</procedure>
     257
     258Column variants of {{row-map}}/{{row-map*}}.
     259
     260<examples>
     261<example>
     262<init>(use postgresql)</init>
     263<expr>
     264(let ((conn (connect '((dbname . test)))))
     265   (column-map* +
     266                (query conn "SELECT 1, 100 UNION SELECT 2, 200")))
     267</expr>
     268<result>
     269(3 300)
     270</result>
     271</example>
     272</examples>
     273
     274==== Low-level API
     275
     276<procedure>(result? OBJ)</result>
     277
     278Returns {{#t}} when {{OBJ}} is a result object, {{#f}} otherwise.
     279
     280<procedure>(clear-result! RES)</procedure>
     281
     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.
     285
     286<procedure>(value-at RES ROW COLUMN [raw: RAW])</procedure>
     287
     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.
     292
     293See [[#type-conversion|type conversion]] for more info on parsers.
     294
     295<procedure>(row-values RES ROW [raw: RAW])</procedure>
     296
     297Returns a list of all the columns' values at the given {{ROW}} number.
     298
     299<procedure>(column-values RES ROW [raw: RAW])</procedure>
     300
     301Returns a list of all the rows' values at the given {{COLUMN}} number.
     302
     303<procedure>(row-alist RES ROW)</procedure>
     304
     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.
     307
     308<procedure>(affected-rows RES)</procedure>
     309
     310For INSERT or UPDATE statements, this returns the number of rows
     311affected by the statement that RES is a result for.  Otherwise it's
     312zero.
     313
     314<procedure>(inserted-oid RES)</procedure>
     315
     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.
     320
     321<procedure>(row-count RES)</procedure>
     322
     323Returns the number of rows in the result set.
     324
     325<procedure>(column-count RES)</procedure>
     326
     327Returns the number of columns in the result set.
     328
     329<procedure>(column-index RES COLUMN)</procedure>
     330
     331Returns the index of {{COLUMN}} in the result set. {{COLUMN}} should
     332be a symbol indicating the column name.
     333
     334<procedure>(column-name RES INDEX)</procedure>
     335
     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.
     339
     340<procedure>(column-names RES)</procedure>
     341
     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.
     345
     346<procedure>(column-format RES INDEX)</procedure>
     347
     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.
     351
     352<procedure>(column-type RES INDEX)</procedure>
     353
     354Returns the OID (an integer) of the column at {{INDEX}}.
     355
     356<procedure>(column-type-modifier RES INDEX)</procedure>
     357
     358Returns an type-specific modifier (a number), or {{#f}} if the type
     359has no modifier.
     360
     361<procedure>(table-oid RES INDEX)</procedure>
     362
     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.
     366
     367<procedure>(table-column-index RES INDEX)</procedure>
     368
     369Returns the column number (within its table) of the column making up
     370the query result column at the position specified by {{INDEX}}.
     371
     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.
     375
     376
     377==== Value escaping
     378
     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).
     383
     384<procedure>(escape-string CONNECTION STRING)</procedure>
     385
     386Quotes special characters in {{STRING}} which are otherwise
     387interpreted by the SQL parser, obeying the {{CONNECTION}}'s encoding
     388settings.
     389
     390<procedure>(escape-bytea CONNECTION STRING)</procedure>
     391
     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
     395columns.
     396
     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.
     400
     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 :)
     406
     407<procedure>(unescape-bytea STRING)</procedure>
     408
     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)
    129413
    130414==== Constants
    131415
    132 <constant>(sql-null-object)</constant>
    133 
    134 Represents SQL {{NULL}} values.
     416<constant>invalid-oid</constant>
     417
     418Represents the numeric value of the invalid Oid.  Rarely useful,
     419except perhaps when doing low-level operations in the system catalog.
    135420
    136421==== Error handling
     
    138423  condition: postgresql
    139424
    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}}.
    144429
    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 [[http://www.postgresql.org/docs/8.1/static/errcodes-appendix.html|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 [[http://www.postgresql.org/docs/8.3/static/errcodes-appendix.html|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.
    155440
    156 ==== Conversion
    157 
    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:
    162 
    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>
    194 
    195 
    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.
    197 
    198 2. These are just returned as text for now.
    199 
    200 === Example
    201 
    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
     442
     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).
     448
     449===== Parsers
     450
     451<parameter>(default-type-parsers [ALIST])</parameter>
     452
     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.
     456
     457The alist is a mapping of Postgres type names (strings) to procedures
     458accepting a string and returning a Scheme object of the desired type.
     459
     460The parsers can also be set per connection with the {{TYPE-PARSERS}}
     461argument of the {{connect}} procedure.
     462
     463<examples>
     464<example>
     465<init>(use postgresql)</init>
     466<expr>
     467(parameterize ((default-type-parsers `(("text" . ,string->symbol))))
     468  (let ((conn (connect '((dbname . test)))))
     469    (row-map identity (query conn "SELECT 'hello'::text"))))
     470</expr>
     471<result>
     472(hello)
     473</result>
     474</example>
     475</examples>
     476
     477The default parsers look like this:
     478
     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))
     492</enscript>
     493
     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).
     497
     498<procedure>(update-type-parsers! CONN [TYPE-PARSERS])</procedure>
     499
     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.
     506
     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.
     512
     513<procedure>(bool-parser STR)</procedure>
     514
     515Returns {{#t}} if the string equals {{"t"}}, {{#f}} otherwise.
     516
     517<procedure>(bytea-parser STR)</procedure>
     518
     519Returns a u8vector containing the bytes in STR, after unescaping it
     520using {{unescape-bytea}}.
     521
     522<procedure>(char-parser STR)</procedure>
     523
     524Returns the first character in STR.
     525
     526<procedure>(numeric-parser STR)</procedure>
     527
     528Returns {{STR}} converted to a number using decimal representation.
     529If {{STR}} could not be converted to a number, raises an error.
     530
     531===== Unparsers
     532
     533<parameter>(default-type-unparsers [ALIST])</parameter>
     534
     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.
     541
     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.
     547
     548It is not necessary to reload type unparsers after defining a new data
     549type in the database.
     550
     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.
     556
     557The default unparsers look like this:
     558
     559<enscript highlight=scheme>
     560`((,string? . ,identity)
     561  (,u8vector? . ,u8vector->blob/shared)
     562  (,char? . ,string)
     563  (,boolean? . ,bool-unparser)
     564  (,number? . ,number->string))
     565</enscript>
     566
     567<procedure>(bool-unparser B)</procedure>
     568
     569Returns {{"TRUE"}} for true values and {{"FALSE"}} for {{#f}}.
    219570
    220571=== Changelog
    221572
    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
    238590
     591  Copyright (C) 2008-2009 Peter Bex
    239592  Copyright (C) 2004 Johannes GrÞdem <johs@copyleft.no>
    240593  Redistribution and use in source and binary forms, with or without
Note: See TracChangeset for help on using the changeset viewer.