File: PostgresDB.k

package info (click to toggle)
kaya 0.4.4-6.2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 5,200 kB
  • ctags: 2,015
  • sloc: cpp: 9,556; haskell: 7,253; sh: 3,060; yacc: 910; makefile: 816; perl: 90
file content (115 lines) | stat: -rw-r--r-- 4,109 bytes parent folder | download | duplicates (4)
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
/** -*-C-*-ish
    Kaya standard library
    Copyright (C) 2004, 2005 Edwin Brady

    This file is distributed under the terms of the GNU Lesser General
    Public Licence. See COPYING for licence.
*/
"<summary>PostgreSQL database interface module</summary>
<prose>This module allows querying of <link url='http://www.postgresql.org'>PostgreSQL</link> databases, using the standard <moduleref>DB</moduleref> API.</prose>"
module PostgresDB;

import Builtins;

// Postgres API suitable for use with the DB module.

import Prelude;
import public DB;

%include "pg_inter.h";
%imported "pg_inter";
%link "pq";

"<summary>A PostgreSQL database connection</summary>
<prose>This data type holds information about a database connection.
The type <code>PGDB</code> is a type synonym for <code>DB::DBHandle&lt;PGConnection></code></prose>
<related><moduleref>DB</moduleref></related>"
abstract data PGConnection = PGCon(Ptr cdata);

type PGDB = DBHandle<PGConnection>;

foreign "pg_inter.o" {
    Ptr pg_connect(String info) = pg_connect;
    Bool pg_ok(Ptr p) = pg_ok;
    Ptr pg_exec(Ptr vm, Ptr cdata, String query, a errstr) = pg_exec;
    [[DBValue]] pg_getstrs(Ptr pr) = pg_getstrs;
    Int pg_numrows(Ptr pr) = pg_numrows;
    Int pg_numcols(Ptr pr) = pg_numcols;
    [String] pg_colnames(Ptr pr) = pg_colnames;
    String pg_getError(Ptr pgc) = pg_getError;
    Void pg_close(Ptr cdata) = pg_close;
    Ptr do_pgprepare(String query) = do_pg_prepare;
    Ptr pg_execp(Ptr vm, Ptr cdata, Ptr query, a errstr, [Maybe<String>] params) = pg_execp;
}

"<argument>The String contains a description of the error</argument>
<summary>Connection error</summary>
<prose>This Exception is thrown if the connection failed.</prose>"
Exception CantConnect(String err);
"<argument>The String contains a description of the error</argument>
<summary>Query error</summary>
<prose>This Exception is thrown if a query failed.</prose>"
Exception ExecError(String err);
"<summary>Column out of range.</summary>
<prose>This Exception should never occur. It is thrown if an attempt is made to read a column that doesn't exist.</prose>"
Exception ColumnOutOfRange();

"<argument name='info'>The database host to connect to. The syntax for this argument is described in <link url='http://www.postgresql.org/docs/8.2/static/libpq-connect.html'>the Postgres documentation</link>.</argument>
<summary>Connect to a database.</summary>
<prose>Use this function to connect to the database. You can then use the functions from <moduleref>DB</moduleref> to query the database.</prose>
<example>conninfo = \"dbname='mysite' user='web' password='WHSpWXPPh5'\";
db = PostgresDB::connect(conninfo);
res = exec(db,\"SELECT * FROM pagedata WHERE page_id = 10\");</example>
<related><moduleref>DB</moduleref></related>"
public DBHandle<PGConnection> connect(String info)
{
    pgc = pg_connect(info);
    if (pg_ok(pgc)==false) {
	throw(CantConnect(pg_getError(pgc)));
    }
    con = PGCon(pgc);
    return(DBh(con,
	       exec_pg, defaultIncExec,
	       prepare_pg, execp_pg, defaultIncExecPrepared,
	       defaultGetRow, defaultIncDiscard, close_pg));
}

DBStatement<PGConnection> prepare_pg(PGDB con, String query) {
  return DBStatement(con,do_pgprepare(query));
}

DBResult execp_pg(DBStatement<PGConnection> prep, [Maybe<String>] params) {
    err = "Unknown error";
    pr = pg_execp(getVM(),prep.con.handle.cdata, prep.statement, err, params);
    if (null(pr)) {
	throw(ExecError(err));
    }
    strs = pg_getstrs(pr);
    rows = pg_numrows(pr);
    cols = pg_numcols(pr);
    colnames = pg_colnames(pr);

    return DBRes(strs,rows,cols,colnames,pr); 
}

"Execute a query on the given connection."
DBResult exec_pg(PGConnection con, String query)
{
    err = "Unknown error";
    pr = pg_exec(getVM(),con.cdata, query, err);
    if (null(pr)) {
	throw(ExecError(err));
    }
    strs = pg_getstrs(pr);
    rows = pg_numrows(pr);
    cols = pg_numcols(pr);
    colnames = pg_colnames(pr);

    return DBRes(strs,rows,cols,colnames,pr);
}

"Close a connection to the database."
Void close_pg(PGConnection con)
{
    pg_close(con.cdata);
}