1 #include "RS-MySQL.h"
2 
3 static MySQLDriver* dbManager = NULL;
rmysql_driver()4 MySQLDriver* rmysql_driver() {
5   if (!dbManager) error("Corrupt MySQL handle");
6   return dbManager;
7 }
8 
rmysql_driver_valid()9 SEXP rmysql_driver_valid() {
10   if(!dbManager || !dbManager->connections) {
11     return ScalarLogical(FALSE);
12   } else {
13     return ScalarLogical(TRUE);
14   }
15 }
16 
rmysql_driver_init(SEXP max_con_,SEXP fetch_default_rec_)17 SEXP rmysql_driver_init(SEXP max_con_, SEXP fetch_default_rec_) {
18   SEXP mgrHandle = ScalarInteger(0);
19   if (dbManager) return mgrHandle;
20   PROTECT(mgrHandle);
21 
22   int max_con = asInteger(max_con_),
23       fetch_default_rec = asInteger(fetch_default_rec_);
24 
25   int counter = 0;
26   MySQLDriver* mgr = (MySQLDriver*) malloc(sizeof(MySQLDriver));
27   if (!mgr)
28     error("Could not allocate memory for the MySQL driver");
29 
30   /* Ok, we're here to expand number of connections, etc.*/
31   mgr->managerId = 0;
32   mgr->connections = calloc(max_con, sizeof(RS_DBI_connection));
33   if (!mgr->connections) {
34     free(mgr);
35     error("Could not allocate memory for connections");
36   }
37 
38   mgr->connectionIds = calloc(max_con, sizeof(int));
39   if (!mgr->connectionIds){
40     free(mgr->connections);
41     free(mgr);
42     error("Could not allocation memory for connection Ids");
43   }
44   mgr->counter = counter;
45   mgr->length = max_con;
46   mgr->num_con = (int) 0;
47   mgr->fetch_default_rec = fetch_default_rec;
48 
49   for(int i = 0; i < max_con; i++){
50     mgr->connectionIds[i] = -1;
51     mgr->connections[i] = (RS_DBI_connection *) NULL;
52   }
53 
54   dbManager = mgr;
55   UNPROTECT(1);
56   return mgrHandle;
57 }
58 
rmysql_driver_close()59 SEXP rmysql_driver_close() {
60   MySQLDriver *mgr = rmysql_driver();
61 
62   if(mgr->num_con)
63     error("Open connections -- close them first");
64 
65   if(mgr->connections) {
66     free(mgr->connections);
67     mgr->connections = (RS_DBI_connection **) NULL;
68   }
69 
70   if(mgr->connectionIds) {
71     free(mgr->connectionIds);
72     mgr->connectionIds = (int *) NULL;
73   }
74 
75   return ScalarLogical(TRUE);
76 }
77 
rmysql_driver_info()78 SEXP rmysql_driver_info() {
79   MySQLDriver *mgr = rmysql_driver();
80 
81   // Allocate output
82   SEXP output = PROTECT(allocVector(VECSXP, 6));
83   SEXP output_nms = PROTECT(allocVector(STRSXP, 6));
84   SET_NAMES(output, output_nms);
85   UNPROTECT(1);
86 
87   SET_CHR_EL(output_nms, 0, mkChar("connectionIds"));
88   SEXP cons = PROTECT(allocVector(INTSXP, mgr->num_con));
89   RS_DBI_listEntries(mgr->connectionIds, mgr->num_con, INTEGER(cons));
90   SET_VECTOR_ELT(output, 0, cons);
91   UNPROTECT(1);
92 
93   SET_CHR_EL(output_nms, 1, mkChar("fetch_default_rec"));
94   SET_VECTOR_ELT(output, 1, ScalarInteger(mgr->fetch_default_rec));
95 
96   SET_CHR_EL(output_nms, 2, mkChar("length"));
97   SET_VECTOR_ELT(output, 2, ScalarInteger(mgr->length));
98 
99   SET_CHR_EL(output_nms, 3, mkChar("num_con"));
100   SET_VECTOR_ELT(output, 3, ScalarInteger(mgr->num_con));
101 
102   SET_CHR_EL(output_nms, 4, mkChar("counter"));
103   SET_VECTOR_ELT(output, 4, ScalarInteger(mgr->counter));
104 
105   SET_CHR_EL(output_nms, 5, mkChar("clientVersion"));
106   SET_VECTOR_ELT(output, 5, mkString(mysql_get_client_info()));
107 
108   UNPROTECT(1);
109   return output;
110 }
111