source: tags/0.5/flatfile_pool.cpp @ 9

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

willem

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