source: tags/0.5/files_pool.cpp @ 9

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

willem

File size: 4.5 KB
Line 
1#include "files_pool.h"
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5#include <stdlib.h>
6#include "wutils.h"
7#include <string.h>
8#include <strings.h>
9#include <stdio.h>
10#include <algorithm>
11#include <fstream>
12#include "stopos.h"
13
14// constructor
15files_pool::files_pool()
16{
17  this->dir_suffix = "_stopos_files_dir";
18}
19
20// own version of set_db_name.
21// this will be a directory, and on creation
22// it will be recursively removed.
23// to avoid oopses, a special name is formed from the input
24void files_pool::set_db_name(std::string filename)
25{
26  this->sdb_name = filename + this->dir_suffix;
27  this->db_name  = strdup(sdb_name.c_str());
28}
29
30void files_pool::create_fname(std::string &fname,const stopos_key &k)
31{
32  fname = this->sdb_name + "/" + k.str();
33}
34
35int files_pool::get_record(datarecord &r, const stopos_key &k)
36{
37  std::string fname;
38  this->create_fname(fname,k);
39  std::ifstream f;
40  f.open(fname.c_str(),std::fstream::in);
41  if (f.fail())
42    return FETCHERROR;
43
44  char b[this->reclen];
45
46  f.getline(b,this->reclen);
47  if (f.bad())
48    return FETCHERROR;
49
50  r = datarecord(b,dbsep);
51
52  f.close();
53
54  return 0;
55}
56
57int files_pool::put_record(datarecord &r, const stopos_key &k)
58{
59  std::string fname;
60
61  this->create_fname(fname,k);
62
63  std::ofstream f;
64  f.open(fname.c_str(),std::fstream::out);
65  if (f.fail())
66    return STOREERROR;
67
68  std::string buf;
69
70  buf = r.str(dbsep);
71
72  buf.resize(reclen);
73
74  f.write(buf.c_str(),this->reclen);
75  if (f.bad())
76    return STOREERROR;
77
78  f.close();
79  return 0;
80}
81
82int files_pool::remove_record(const stopos_key &k)
83{
84  int rc;
85  std::string fname;
86  this->create_fname(fname,k);
87  rc = unlink(fname.c_str());
88  if (rc == -1)
89    return this->REMOVEERROR;
90
91  return 0;
92}
93
94int files_pool::get_status(void)
95{
96  std::string fname;
97  this->create_fname(fname,this->statuskey);
98
99  std::ifstream f;
100  f.open(fname.c_str(),std::fstream::in);
101  if (f.fail())
102    return FETCHERROR;
103
104  char b[this->reclen];
105
106  f.getline(b,this->reclen);
107  if (f.bad())
108    return FETCHERROR;
109
110  this->status = statusrecord(b,dbsep);
111
112  return 0;
113}
114
115int files_pool::put_status(void)
116{
117  std::string buf;
118  buf = this->status.str(dbsep);
119
120  if (buf.size() > this->reclen)
121    return this->STATUSTOOLONG;
122
123  buf.resize(reclen);
124
125  std::string fname;
126  this->create_fname(fname,this->statuskey);
127
128  std::ofstream f;
129  f.open(fname.c_str(),std::fstream::out);
130  if (f.fail())
131    return STOREERROR;
132
133  f.write(buf.c_str(),this->reclen);
134  if (f.bad())
135    return STOREERROR;
136
137  f.close();
138
139  return 0;
140}
141
142int files_pool::create_db(void)
143{
144  int rc;
145  rc = this->purge_db();
146  if (rc != 0)
147    return rc;
148
149  rc = mkdir_p(this->db_name,0755);
150  if (rc != 0)
151    return rc;
152
153  status.init();
154
155
156  rc = this->open_db();
157  if (rc != 0)
158    return rc;
159
160  rc = put_status();
161  if (rc != 0)
162  {
163    this->close_db();
164    return this->STOREERROR;
165  }
166
167  this->close_db();
168
169  return 0;
170}
171
172int files_pool::purge_db(void)
173{
174  if (this->db_name == 0)
175    return NOFILENAME;
176
177  if ( strstr(this->db_name,"_stopos_files_dir") == 0)
178    return NOTDIR;
179
180  std::string command;
181  command = "rm -rf " + this->sdb_name;
182  int rc = system(command.c_str());
183  if (rc != 0)
184    ;
185  return 0;
186}
187
188int files_pool::open_db(void)
189{
190  if (this->db_name == 0)
191    return NOFILENAME;
192
193  if (this->db_open)
194    return 0;
195
196  // create lockfilename
197  this->lockfilename = this->sdb_name+"/lockfile";
198
199  int rc = access(this->db_name,R_OK|W_OK);
200  if (rc == -1)
201    return OPENERROR;
202
203  struct stat status;
204  stat(this->db_name, &status );
205
206  if ( !(status.st_mode & S_IFDIR) )
207     return OPENERROR;
208
209  this->lockfile = open(this->lockfilename.c_str(),O_CREAT|O_RDWR,0600);
210  if (this->lockfile < 0)
211    return LOCKERROR;
212
213  struct flock lock;
214  lock.l_type = F_RDLCK|F_WRLCK;
215  lock.l_whence = SEEK_SET;
216  lock.l_start  = 0;
217  lock.l_len    = 0;
218
219  rc = fcntl(this->lockfile,F_SETLKW,&lock);
220  if (rc < 0)
221    return LOCKERROR;
222
223  this->db_open = 1;
224
225  return 0;
226}
227
228int files_pool::close_db(void)
229{
230  if (!this->db_open)
231    return 0;
232
233  struct flock lock;
234  lock.l_type = F_UNLCK;
235  lock.l_whence = SEEK_SET;
236  lock.l_start  = 0;
237  lock.l_len    = 0;
238
239  int rc = fcntl(this->lockfile,F_SETLKW,&lock);
240  if (rc < 0)
241    return UNLOCKERROR;
242
243  close(this->lockfile);
244
245  this->db_open = 0;
246
247  return 0;
248}
249
250void files_pool::dump_db(void)
251{
252  std::string command;
253  command ="(for i in ";
254  command += db_name;
255  command += "/* ; do echo -n `basename $i`:;cat $i | tr -d '\\0' ; echo ; done |sort -n ) 1>&2";
256  int rc = system(command.c_str());
257  if (rc)
258    ;
259}
Note: See TracBrowser for help on using the repository browser.