started working on the nit wrapper over the native postgres wrapper
[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 # A native wrapper ove the postgres c api
18 module native_postgres is pkgconfig("libpq")
19
20 in "C header" `{
21 #include <libpq-fe.h>
22 `}
23
24 extern class ExecStatusType `{int`}
25 new empty `{ return PGRES_EMPTY_QUERY; `}
26 new command_ok `{ return PGRES_COMMAND_OK; `}
27 new tuples_ok `{ return PGRES_TUPLES_OK; `}
28 new copy_out `{ return PGRES_COPY_OUT; `}
29 new copy_in `{ return PGRES_COPY_IN; `}
30 new bad_response `{ return PGRES_BAD_RESPONSE; `}
31 new nonfatal_error `{ return PGRES_NONFATAL_ERROR; `}
32 new fatal_error `{ return PGRES_FATAL_ERROR; `}
33
34 fun is_ok: Bool `{
35 return !(self == PGRES_BAD_RESPONSE || self == PGRES_NONFATAL_ERROR || self == PGRES_FATAL_ERROR);
36 `}
37
38 redef fun to_s import NativeString.to_s `{
39 char * err = PQresStatus(self);
40 if(err == NULL) err = "";
41 return NativeString_to_s(err);
42 `}
43 end
44
45 extern class ConnStatusType `{int`}
46 new connection_ok `{ return CONNECTION_OK; `}
47 new connection_bad `{ return CONNECTION_BAD; `}
48
49 fun is_ok: Bool `{return self == CONNECTION_OK; `}
50 end
51
52 extern class NativePGResult `{PGresult *`}
53 # Frees the memory block associated with the result
54 fun clear `{PQclear(self); `}
55
56 # Returns the number of rows in the query result
57 fun ntuples:Int `{ return PQntuples(self); `}
58
59 # Returns the number of columns in each row of the query result
60 fun nfields:Int `{return PQnfields(self); `}
61
62 # Returns the ExecStatusType of a result
63 fun status: ExecStatusType `{ return PQresultStatus(self); `}
64
65 # Returns the field name of a given column_number
66 fun fname(column_number:Int):String import NativeString.to_s `{
67 return NativeString_to_s( PQfname(self, column_number));
68 `}
69
70 # Returns the column number associated with the column name
71 fun fnumber(column_name:String):Int import String.to_cstring `{
72 return PQfnumber(self, String_to_cstring(column_name));
73 `}
74
75 # Returns a single field value of one row of the result at row_number, column_number
76 fun value(row_number:Int, column_number:Int):String import NativeString.to_s `{
77 return NativeString_to_s(PQgetvalue(self, row_number, column_number));
78 `}
79
80 # Tests wether a field is a null value
81 fun is_null(row_number:Int, column_number: Int): Bool `{
82 return PQgetisnull(self, row_number, column_number);
83 `}
84
85 end
86 extern class NativePostgres `{PGconn *`}
87
88 # Connect to a new database using the conninfo string as a parameter
89 new connectdb(conninfo: Text) import Text.to_cstring `{
90 PGconn * self = NULL;
91 self = PQconnectdb(Text_to_cstring(conninfo));
92 return self;
93 `}
94
95 # Submits a query to the server and waits for the result returns the ExecStatustype of the query
96 fun exec(query: Text): NativePGResult import Text.to_cstring `{
97 PGresult *res = PQexec(self, Text_to_cstring(query));
98 return res;
99 `}
100
101 # Prepares a statement with the given parameters
102 fun prepare(stmt: String, query: String, nParams: Int): NativePGResult import String.to_cstring `{
103 const char * stmtName = String_to_cstring(stmt);
104 const char * queryStr = String_to_cstring(query);
105 PGresult * res = PQprepare(self, stmtName, queryStr, nParams, NULL);
106 return res;
107 `}
108
109 fun exec_prepared(stmt: String, nParams: Int, values: Array[String], pLengths: Array[Int], pFormats: Array[Int], resultFormat: Int): NativePGResult import String.to_cstring, Array[String].[], Array[Int].[] `{
110 const char * stmtName = String_to_cstring(stmt);
111 const char * paramValues[nParams];
112 int paramLengths[nParams];
113 int paramFormats[nParams];
114 int i;
115 for(i = 0; i < nParams; i++)
116 paramValues[i] = String_to_cstring(Array_of_String__index(values, i));
117 for(i = 0; i < nParams; i++)
118 paramLengths[i] = Array_of_Int__index(pLengths, i);
119 for(i = 0; i < nParams; i++)
120 paramFormats[i] = Array_of_Int__index(pFormats, i);
121 PGresult * res = PQexecPrepared(self, stmtName, nParams, paramValues, paramLengths, paramFormats, resultFormat);
122 return res;
123 `}
124
125 # Returns the error message of the last operation on the connection
126 fun error: String import NativeString.to_s `{
127 char * error = PQerrorMessage(self);
128 return NativeString_to_s(error);
129 `}
130
131 # Returns the status of this connection
132 fun status: ConnStatusType `{
133 return PQstatus(self);
134 `}
135
136 # Closes the connection to the server
137 fun finish `{
138 PQfinish(self);
139 `}
140
141 # Closes the connection to the server and attempts to reconnect with the previously used params
142 fun reset `{
143 PQreset(self);
144 `}
145 end