source: tags/0.56/flatfile_pool.cpp @ 9

Last change on this file since 9 was 9, checked in by willem, 11 years ago

willem

File size: 4.3 KB
Line 
1#include "flatfile_pool.h"
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <errno.h>
5#include <fcntl.h>
6#include <stdlib.h>
7#include "wutils.h"
8#include <string.h>
9#include <strings.h>
10#include <stdio.h>
11#include <algorithm>
12#include "stopos.h"
13
14// constructor
15flatfile_pool::flatfile_pool()
16{
17}
18
19std::string flatfile_pool::get_slot(const std::string &k)
20{
21  return "";
22}
23
24int flatfile_pool::get_record(std::string &r, const std::string &k)
25{
26  off_t p;
27  int rc;
28
29  p = this->reclen*stopos_key::KeyToNumber<off_t>(k);
30
31  std::string rec;  // wwvv todo no need for rec
32
33  rc = this->read_string(rec,p);
34  if (rc !=0 )
35    return rc;
36
37  if (rec[0] == this->deleted)
38    return this->NOTFOUND;
39
40  rec.erase(0,2); // remove first char plus separator
41  r = rec;
42
43  return 0;
44}
45
46int flatfile_pool::put_record(const std::string &r, const std::string &k)
47{
48  std::string buf;
49
50  buf = buf + this->exists + dbsep + r;
51
52  off_t p = this->reclen*stopos_key::KeyToNumber<off_t>(k);
53
54  return this->write_string(buf,p);
55}
56
57int flatfile_pool::remove_record(const stopos_key &k)
58{
59  int rc;
60
61  off_t p = this->reclen*k.get<off_t>();
62
63  std::string r;
64  rc = this->read_string(r,p);
65  if (rc != 0)
66    return rc;
67
68  r[0] = this->deleted;
69
70  return this->write_string(r,p);
71}
72
73int flatfile_pool::read_string(std::string &r, off_t p)
74{
75
76  //std:: cerr << "\nWTD: " << __LINE__ <<":"<< this->db_open<<std::endl;
77  char b[this->reclen];
78  off_t rc;
79  rc = lseek(this->ff, p, SEEK_SET);
80  if (rc == -1)
81    return FETCHERROR;
82
83  ssize_t rc1;
84  rc1 = read(this->ff, b, this->reclen);
85  if (rc1 != this->reclen)
86    return FETCHERROR;
87
88  r = b;
89
90  return 0;
91}
92
93int flatfile_pool::get_status(void)
94{
95  std::string r;
96  int rc;
97  off_t p = this->reclen*this->statuskey.get<off_t>();
98
99  rc = this->read_string(r,p);
100  if (rc != 0)
101    return rc;
102
103  this->status = statusrecord(r,dbsep);
104
105  return 0;
106}
107
108int flatfile_pool::write_string(const std::string &r, off_t p)
109{
110  int rc;
111  char b[this->reclen];
112
113  rc = lseek(this->ff,p,SEEK_SET);
114  if (rc == -1)
115    return STOREERROR;
116
117  bzero(b, this->reclen);
118  strncpy(b,r.c_str(),r.size());
119  ssize_t first = 0;
120  ssize_t togo  = this->reclen;
121  ssize_t written;
122
123  do
124  {
125    written = write(ff,&b[first],togo);
126    if (written == -1)
127    {
128      perror("write:");
129      return 2;
130    }
131    togo   -= written;
132    first  += written;
133  } while(togo !=0);
134
135  return 0;
136}
137
138int flatfile_pool::put_status(void)
139{
140
141  std::string buf;
142
143  buf = this->status.str(dbsep);
144
145  if (buf.size() > this->reclen)
146    return this->STATUSTOOLONG;
147
148  off_t p = this->reclen*this->statuskey.get<off_t>();
149
150  return write_string(buf,p);
151
152  return 0;
153}
154
155int flatfile_pool::create_db(void)
156{
157  int rc; 
158
159  rc = this->purge_db();
160  if (rc != 0)
161    return rc;
162
163  // The db_name can be composed of parts separated with '/'
164  // we try to create this path until the last '/'
165 
166  size_t p = this->sdb_name.find_last_of('/');
167  rc = mkdir_p(this->sdb_name.substr(0,p+1),0755);
168  if (rc != 0)
169    return CREATEERROR;
170
171  this->open_db();
172
173  this->status.init();
174
175  rc = put_status();
176  if (rc != 0)
177  {
178    this->close_db();
179    return this->STOREERROR;
180  }
181
182  this->close_db();
183
184  return 0;
185}
186
187int flatfile_pool::purge_db(void)
188{
189  if (this->db_name == 0)
190    return NOFILENAME;
191
192  this->close_db();
193
194  unlink(this->db_name);
195  return 0;
196}
197
198int flatfile_pool::open_db(void)
199{
200  int rc;
201
202  if (this->db_name == 0)
203    return NOFILENAME;
204
205  if (this->db_open)
206    return 0;
207
208  this->ff = open(this->db_name, O_CREAT|O_RDWR,0644);
209  if (this->ff < 0)
210    return OPENERROR;
211
212  struct flock lock;
213  lock.l_type   = F_RDLCK|F_WRLCK;
214  lock.l_whence = SEEK_SET;
215  lock.l_start  = 0;
216  lock.l_len    = 0;
217
218  rc = fcntl(this->ff,F_SETLKW,&lock);
219  if (rc < 0)
220    return LOCKERROR;
221
222  this->db_open = 1;
223
224  return 0;
225}
226
227int flatfile_pool::close_db(void)
228{
229  if (!this->db_open)
230     return 0;
231
232  int rc;
233
234  struct flock lock;
235  lock.l_type   = F_UNLCK;
236  lock.l_whence = SEEK_SET;
237  lock.l_start  = 0;
238  lock.l_len    = 0;
239
240  rc = fcntl(this->ff,F_SETLKW,&lock);
241  if (rc < 0)
242    return UNLOCKERROR;
243
244  rc = close(this->ff);
245  if (rc == -1)
246    return CLOSEERROR;
247
248  this->db_open = 0;
249
250  return 0;
251}
252
253void flatfile_pool::dump_db(void)
254{
255  std::string r;
256  off_t n = 1;
257
258  while (read_string(r,n*this->reclen)==0)
259  {
260    std::cerr << r << std::endl;
261    n++;
262  }
263}
Note: See TracBrowser for help on using the repository browser.