1 #ifndef _RS_MYSQL_H
2 #define _RS_MYSQL_H 1
3 // Copyright (C) 1999-2002 The Omega Project for Statistical Computing.
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 
19 #ifdef _cplusplus
20 extern  "C" {
21 #endif
22 
23 
24 #include "S4R.h"
25 
26 #include <mysql.h>
27 #include <string.h>
28 
29 #if MYSQL_VERSION_ID >= 80000 && MYSQL_VERSION_ID < 100000
30 #define my_bool bool
31 #endif
32 
33 // Objects =====================================================================
34 
35 typedef struct RMySQLFields {
36   int num_fields;
37   char  **name;         // DBMS field names
38   int  *type;           // DBMS internal types
39   int  *length;         // DBMS lengths in bytes
40   int  *precision;      // DBMS num of digits for numeric types
41   int  *scale;          // DBMS num of decimals for numeric types
42   int  *nullOk;         // DBMS indicator for DBMS'  NULL type
43   int  *isVarLength;    // DBMS variable-length char type
44   SEXPTYPE *Sclass;     // R/S class (type) -- may be overriden
45 } RMySQLFields;
46 
47 typedef struct st_sdbi_resultset {
48   void  *drvResultSet;   // the actual (driver's) cursor/result set
49   int  managerId;        // the 3 *Id's are used for
50   int  connectionId;     // validating stuff coming from S
51   int  resultSetId;
52   int  isSelect;         // boolean for testing SELECTs
53   char  *statement;      // SQL statement
54   int  rowsAffected;     // used by non-SELECT statements
55   int  rowCount;         // rows fetched so far (SELECT-types)
56   int  completed;        // have we fetched all rows?
57   RMySQLFields* fields;
58 } RS_DBI_resultSet;
59 
60 typedef struct st_sdbi_connection {
61   void  *conParams;                 // pointer to connection params (host, user, etc)
62   void  *drvConnection;             // pointer to the actual DBMS connection struct
63   RS_DBI_resultSet  **resultSets;   // vector to result set ptrs
64   int   *resultSetIds;
65   int   length;                     // max num of concurrent resultSets
66   int   num_res;                    // num of open resultSets
67   int   counter;                    // total number of queries
68   int   managerId;
69   int   connectionId;
70 } RS_DBI_connection;
71 
72 typedef struct st_sdbi_conParams {
73   char *dbname;
74   char *username;
75   char *password;
76   char *host;
77   char *unix_socket;
78   unsigned int  port;
79   unsigned int  client_flag;
80   char *groups;
81   char *default_file;
82 } RS_MySQL_conParams;
83 
84 
85 // dbManager
86 typedef struct MySQLDriver {
87   RS_DBI_connection **connections; // list of dbConnections
88   int *connectionIds;              // array of connectionIds
89   int length;                      // max num of concurrent connections
90   int num_con;                     // num of opened connections
91   int counter;                     // num of connections handled so far
92   int fetch_default_rec;           // default num of records per fetch
93   int managerId;                   // typically, process id
94 } MySQLDriver;
95 
96 // Functions ===================================================================
97 
98 #define MGR_ID(handle) INTEGER(handle)[0]
99 #define CON_ID(handle) INTEGER(handle)[1]
100 #define RES_ID(handle) INTEGER(handle)[2]
101 
102 // Driver ----------------------------------------------------------------------
103 
104 MySQLDriver* rmysql_driver();
105 SEXP rmysql_driver_init(SEXP max_con_, SEXP fetch_default_rec_);
106 SEXP rmysql_driver_info();
107 
108 SEXP rmysql_exception_info(SEXP conHandle);
109 
110 // Connection ------------------------------------------------------------------
111 
112 SEXP RS_DBI_allocConnection(SEXP mgrHandle, int max_res);
113 void RS_DBI_freeConnection(SEXP conHandle);
114 RS_DBI_connection *RS_DBI_getConnection(SEXP handle);
115 SEXP RS_DBI_asConHandle(int mgrId, int conId);
116 SEXP RS_DBI_connectionInfo(SEXP con_Handle);
117 SEXP RS_MySQL_newConnection(SEXP mgrHandle, SEXP s_dbname, SEXP s_username, SEXP s_password, SEXP s_myhost, SEXP s_unix_socket, SEXP s_port, SEXP s_client_flag, SEXP s_groups, SEXP s_default_file);
118 SEXP RS_MySQL_createConnection(SEXP mgrHandle, RS_MySQL_conParams *conParams);
119 SEXP RS_MySQL_cloneConnection(SEXP conHandle);
120 SEXP RS_MySQL_closeConnection(SEXP conHandle);
121 SEXP RS_MySQL_connectionInfo(SEXP conHandle);
122 
123 RS_MySQL_conParams* RS_MySQL_allocConParams(void);
124 RS_MySQL_conParams* RS_MySQL_cloneConParams(RS_MySQL_conParams *conParams);
125 void RS_MySQL_freeConParams(RS_MySQL_conParams *conParams);
126 
127 // Result set ------------------------------------------------------------------
128 SEXP RS_DBI_allocResultSet(SEXP conHandle);
129 void RS_DBI_freeResultSet(SEXP rsHandle);
130 RS_DBI_resultSet* RS_DBI_getResultSet(SEXP rsHandle);
131 SEXP RS_DBI_asResHandle(int pid, int conId, int resId);
132 SEXP RS_DBI_resultSetInfo(SEXP rsHandle);
133 SEXP RS_MySQL_exec(SEXP conHandle, SEXP statement);
134 SEXP RS_MySQL_fetch(SEXP rsHandle, SEXP max_rec);
135 SEXP RS_MySQL_closeResultSet(SEXP rsHandle);
136 SEXP RS_MySQL_nextResultSet(SEXP conHandle);
137 SEXP RS_MySQL_moreResultSets(SEXP conHandle);
138 SEXP RS_MySQL_resultSetInfo(SEXP rsHandle);
139 
140 // Fields ----------------------------------------------------------------------
141 void rmysql_fields_free(RMySQLFields* flds);
142 void RS_DBI_allocOutput(SEXP output, RMySQLFields* flds, int num_rec, int expand);
143 void make_data_frame(SEXP data);
144 SEXP RS_DBI_copyFields(RMySQLFields* flds);
145 RMySQLFields* RS_MySQL_createDataMappings(SEXP resHandle);
146 
147 // Utilities -------------------------------------------------------------------
148 char *RS_DBI_copyString(const char* str);
149 SEXP RS_DBI_createNamedList(char** names, SEXPTYPE* types, int* lengths, int n);
150 void RS_na_set(void* ptr, SEXPTYPE type);
151 int RS_is_na(void* ptr, SEXPTYPE type);
152 SEXP rmysql_escape_strings(SEXP conHandle, SEXP statement);
153 
154 // Object database -------------------------------------------------------------
155 // Simple object database used for storing all connections for a driver,
156 // and all result sets for a connection.
157 int RS_DBI_newEntry(int* table, int length);
158 int RS_DBI_lookup(int* table, int length, int obj_id);
159 int RS_DBI_listEntries(int* table, int length, int* entries);
160 void RS_DBI_freeEntry(int* table, int indx);
161 
162 #ifdef _cplusplus
163 }
164 #endif
165 
166 #endif   // _RS_MYSQL_H
167