4d222010597db1d8df621a01366aa53f360f08cb
[nit.git] / lib / postgresql / native_postgres.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2015-2016 Guilherme Mansur <guilhermerpmansur@gmail.com>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 module native_postgres is pkgconfig("libpq")
18
19 in "C header" `{
20 #include <libpq-fe.h>
21 `}
22
23 extern class ExecStatusType `{int`}
24 new empty `{ return PGRES_EMPTY_QUERY; `}
25 new command_ok `{ return PGRES_COMMAND_OK; `}
26 new tuples_ok `{ return PGRES_TUPLES_OK; `}
27 new copy_out `{ return PGRES_COPY_OUT; `}
28 new copy_in `{ return PGRES_COPY_IN; `}
29 new bad_response `{ return PGRES_BAD_RESPONSE; `}
30 new nonfatal_error `{ return PGRES_NONFATAL_ERROR; `}
31 new fatal_error `{ return PGRES_FATAL_ERROR; `}
32
33 fun is_ok: Bool `{return self == PGRES_TUPLES_OK || self == PGRES_COMMAND_OK; `}
34
35 redef fun to_s import NativeString.to_s `{
36 char * err = PQresStatus(self);
37 if(err == NULL) err = "";
38 return NativeString_to_s(err);
39 `}
40 end
41
42 extern class ConnStatusType `{int`}
43 new connection_ok `{ return CONNECTION_OK; `}
44 new connection_bad `{ return CONNECTION_BAD; `}
45
46 fun is_ok: Bool `{return self == CONNECTION_OK; `}
47 end
48
49 extern class PGResult `{PGresult *`}
50 # Frees the memory block associated with the result
51 fun clear `{PQclear(self); `}
52
53 # Returns the number of rows in the query result
54 fun ntuples:Int `{ return PQntuples(self); `}
55
56 # Returns the number of columns in each row of the query result
57 fun nfields:Int `{return PQnfields(self); `}
58
59 # Returns the ExecStatusType of a result
60 fun status: ExecStatusType `{ return PQresultStatus(self); `}
61
62 # Returns the field name of a given column_number
63 fun fname(column_number:Int):String import NativeString.to_s `{
64 return NativeString_to_s( PQfname(self, column_number));
65 `}
66
67 # Returns the column number associated with the column name
68 fun fnumber(column_name:String):Int import String.to_cstring `{
69 return PQfnumber(self, String_to_cstring(column_name));
70 `}
71
72 # Returns a single field value of one row of the result at row_number, column_number
73 fun value(row_number:Int, column_number:Int):String import NativeString.to_s `{
74 return NativeString_to_s(PQgetvalue(self, row_number, column_number));
75 `}
76
77 # Tests wether a field is a null value
78 fun is_null(row_number:Int, column_number: Int): Bool `{
79 return PQgetisnull(self, row_number, column_number);
80 `}
81
82 end
83 extern class NativePostgres `{PGconn *`}
84
85 # Connect to a new database using the conninfo string as a parameter
86 new connectdb(conninfo: String) import String.to_cstring `{
87 PGconn * self = NULL;
88 self = PQconnectdb(String_to_cstring(conninfo));
89 return self;
90 `}
91
92 # Submits a query to the server and waits for the result returns the ExecStatustype of the query
93 fun exec(query: String): PGResult import String.to_cstring `{
94 PGresult *res = PQexec(self, String_to_cstring(query));
95 return res;
96 `}
97
98 # Prepares a statement with the given parameters
99 fun prepare(stmt: String, query: String, nParams: Int):PGResult import String.to_cstring `{
100 const char * stmtName = String_to_cstring(stmt);
101 const char * queryStr = String_to_cstring(query);
102 PGresult * res = PQprepare(self, stmtName, queryStr, nParams, NULL);
103 return res;
104 `}
105
106 fun exec_prepared(stmt: String, nParams: Int, values: Array[String], pLengths: Array[Int], pFormats: Array[Int], resultFormat: Int):PGResult import String.to_cstring, Array[String].[], Array[Int].[] `{
107 const char * stmtName = String_to_cstring(stmt);
108 const char * paramValues[nParams];
109 int paramLengths[nParams];
110 int paramFormats[nParams];
111 int i;
112 for(i = 0; i < nParams; i++)
113 paramValues[i] = String_to_cstring(Array_of_String__index(values, i));
114 for(i = 0; i < nParams; i++)
115 paramLengths[i] = Array_of_Int__index(pLengths, i);
116 for(i = 0; i < nParams; i++)
117 paramFormats[i] = Array_of_Int__index(pFormats, i);
118 PGresult * res = PQexecPrepared(self, stmtName, nParams, paramValues, paramLengths, paramFormats, resultFormat);
119 return res;
120 `}
121
122 # Returns the error message of the last operation on the connection
123 fun error: String import NativeString.to_s `{
124 char * error = PQerrorMessage(self);
125 return NativeString_to_s(error);
126 `}
127
128 # Returns the status of this connection
129 fun status: ConnStatusType `{
130 return PQstatus(self);
131 `}
132
133 # Closes the connection to the server
134 fun finish `{
135 PQfinish(self);
136 `}
137
138 # Closes the connection to the server and attempts to reconnect with the previously used params
139 fun reset `{
140 PQreset(self);
141 `}
142 end