Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00033 #include "flat_con.h"
00034 #include "flatstore_mod.h"
00035 #include "flat_uri.h"
00036
00037 #include "../../mem/mem.h"
00038 #include "../../dprint.h"
00039 #include "../../ut.h"
00040
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <errno.h>
00045
00046
00053 static void flat_con_free(db_con_t* con, struct flat_con* payload)
00054 {
00055 int i;
00056 if (!payload) return;
00057
00058
00059
00060
00061 if (db_pool_remove((db_pool_entry_t*)payload) == 0) return;
00062
00063 db_pool_entry_free(&payload->gen);
00064
00065 if (payload->file) {
00066 for(i = 0; i < payload->n; i++) {
00067 if (payload->file[i].filename) pkg_free(payload->file[i].filename);
00068 if (payload->file[i].table.s) pkg_free(payload->file[i].table.s);
00069 if (payload->file[i].f) fclose(payload->file[i].f);
00070 }
00071 pkg_free(payload->file);
00072 }
00073 pkg_free(payload);
00074 }
00075
00076
00077 int flat_con(db_con_t* con)
00078 {
00079 struct flat_con* fcon;
00080
00081
00082
00083
00084 fcon = (struct flat_con*)db_pool_get(con->uri);
00085 if (fcon) {
00086 DBG("flatstore: A handle to %.*s found in the connection pool\n",
00087 STR_FMT(&con->uri->body));
00088 goto found;
00089 }
00090
00091 fcon = (struct flat_con*)pkg_malloc(sizeof(struct flat_con));
00092 if (fcon == NULL) {
00093 ERR("flatstore: No memory left\n");
00094 goto error;
00095 }
00096 memset(fcon, '\0', sizeof(struct flat_con));
00097 if (db_pool_entry_init(&fcon->gen, flat_con_free, con->uri) < 0) goto error;
00098
00099 DBG("flastore: Preparing new file handles to files in %.*s\n",
00100 STR_FMT(&con->uri->body));
00101
00102
00103 db_pool_put((struct db_pool_entry*)fcon);
00104 DBG("flatstore: Handle stored in connection pool\n");
00105
00106 found:
00107
00108
00109
00110 DB_SET_PAYLOAD(con, fcon);
00111 con->connect = flat_con_connect;
00112 con->disconnect = flat_con_disconnect;
00113 return 0;
00114
00115 error:
00116 if (fcon) {
00117 db_pool_entry_free(&fcon->gen);
00118 pkg_free(fcon);
00119 }
00120 return -1;
00121 }
00122
00123
00124 int flat_con_connect(db_con_t* con)
00125 {
00126 struct flat_con* fcon;
00127 int i;
00128
00129 fcon = DB_GET_PAYLOAD(con);
00130
00131
00132 if (fcon->flags & FLAT_OPENED) return 0;
00133
00134 DBG("flatstore: Opening handles to files in '%.*s'\n",
00135 STR_FMT(&con->uri->body));
00136
00137
00138
00139
00140
00141 DBG("flatstore: Directory '%.*s' opened successfully\n",
00142 STR_FMT(&con->uri->body));
00143
00144 for(i = 0; i < fcon->n; i++) {
00145 if (fcon->file[i].f) {
00146 fclose(fcon->file[i].f);
00147 }
00148 fcon->file[i].f = fopen(fcon->file[i].filename, "a");
00149 if (fcon->file[i].f == NULL) {
00150 ERR("flatstore: Error while opening file handle to '%s': %s\n",
00151 fcon->file[i].filename, strerror(errno));
00152 return -1;
00153 }
00154 }
00155
00156 fcon->flags |= FLAT_OPENED;
00157 return 0;
00158
00159 }
00160
00161
00162 void flat_con_disconnect(db_con_t* con)
00163 {
00164 struct flat_con* fcon;
00165 int i;
00166
00167 fcon = DB_GET_PAYLOAD(con);
00168
00169 if ((fcon->flags & FLAT_OPENED) == 0) return;
00170
00171 DBG("flatstore: Closing handles to files in '%.*s'\n",
00172 STR_FMT(&con->uri->body));
00173
00174 for(i = 0; i < fcon->n; i++) {
00175 if (fcon->file[i].f == NULL) continue;
00176 fclose(fcon->file[i].f);
00177 fcon->file[i].f = NULL;
00178 }
00179
00180 fcon->flags &= ~FLAT_OPENED;
00181 }
00182
00183
00184
00185 static char* get_filename(str* dir, str* name)
00186 {
00187 char* buf, *p;
00188 int buf_len, total_len;
00189
00190 buf_len = pathmax();
00191
00192 total_len = dir->len + 1 +
00193 name->len + 1 +
00194 flat_pid.len +
00195 flat_suffix.len + 1 ;
00196
00197 if (buf_len < total_len) {
00198 ERR("flatstore: The path is too long (%d and PATHMAX is %d)\n",
00199 total_len, buf_len);
00200 return 0;
00201 }
00202
00203 if ((buf = pkg_malloc(buf_len)) == NULL) {
00204 ERR("flatstore: No memory left\n");
00205 return 0;
00206 }
00207 p = buf;
00208
00209 memcpy(p, dir->s, dir->len);
00210 p += dir->len;
00211
00212 *p++ = '/';
00213
00214 memcpy(p, name->s, name->len);
00215 p += name->len;
00216
00217 *p++ = '_';
00218
00219 memcpy(p, flat_pid.s, flat_pid.len);
00220 p += flat_pid.len;
00221
00222 memcpy(p, flat_suffix.s, flat_suffix.len);
00223 p += flat_suffix.len;
00224
00225 *p = '\0';
00226 return buf;
00227 }
00228
00229
00230
00231 int flat_open_table(int* idx, db_con_t* con, str* name)
00232 {
00233 struct flat_uri* furi;
00234 struct flat_con* fcon;
00235 struct flat_file* new;
00236 int i;
00237 char* filename, *table;
00238
00239 new = NULL;
00240 filename = NULL;
00241 table = NULL;
00242 fcon = DB_GET_PAYLOAD(con);
00243 furi = DB_GET_PAYLOAD(con->uri);
00244
00245 for(i = 0; i < fcon->n; i++) {
00246 if (name->len == fcon->file[i].table.len &&
00247 !strncmp(name->s, fcon->file[i].table.s, name->len))
00248 break;
00249 }
00250 if (fcon->n == i) {
00251
00252
00253
00254
00255 if ((filename = get_filename(&furi->path, name)) == NULL)
00256 goto no_mem;
00257
00258 if ((table = pkg_malloc(name->len)) == NULL) goto no_mem;
00259 memcpy(table, name->s, name->len);
00260
00261 new = pkg_realloc(fcon->file, sizeof(struct flat_file) * (fcon->n + 1));
00262 if (new == NULL) goto no_mem;
00263
00264 fcon->file = new;
00265 new = new + fcon->n;
00266 fcon->n++;
00267
00268 new->table.s = table;
00269 new->table.len = name->len;
00270 new->filename = filename;
00271
00272
00273 if (fcon->flags & FLAT_OPENED) {
00274 if ((new->f = fopen(new->filename, "a")) == NULL) {
00275 ERR("flatstore: Error while opening file handle to '%s': %s\n",
00276 new->filename, strerror(errno));
00277 return -1;
00278 }
00279 } else {
00280 new->f = NULL;
00281 }
00282
00283 *idx = fcon->n - 1;
00284 } else {
00285 *idx = i;
00286 }
00287 DBG("flatstore: Handle to file '%s' opened successfully\n",
00288 fcon->file[*idx].filename);
00289 return 0;
00290
00291 no_mem:
00292 ERR("flatstore: No memory left\n");
00293 if (filename) pkg_free(filename);
00294 if (table) pkg_free(table);
00295 return -1;
00296 }
00297
00298