From 8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 Mon Sep 17 00:00:00 2001 From: Constantin Jucovschi Date: Fri, 24 Apr 2009 07:20:22 -0400 Subject: Initial commit --- relblobif/simplefilestorage.cc | 178 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 relblobif/simplefilestorage.cc (limited to 'relblobif/simplefilestorage.cc') diff --git a/relblobif/simplefilestorage.cc b/relblobif/simplefilestorage.cc new file mode 100644 index 0000000..02548bc --- /dev/null +++ b/relblobif/simplefilestorage.cc @@ -0,0 +1,178 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +/************************************************************* + * + * + * PURPOSE: + * The interface used by the file storage modules. + * + * + * COMMENTS: + * + ************************************************************/ + +#include +#include +#include +#include +#include "raslib/rminit.hh" +#include "../reladminif/oidif.hh" +#include "simplefilestorage.hh" +#include "debug-srv.hh" + +using namespace std; + +SimpleFileStorage::~SimpleFileStorage() +{ +} + +SimpleFileStorage::SimpleFileStorage(const string& path) throw (r_Error) : root_path(path) +{ + // Check if the path exist is readable/writable etc. + struct stat status; + if (stat(path.c_str(), &status)<0 || !S_ISDIR(status.st_mode)) { + throw 1; // Root directory not found + } + TALK("SimpleFileStorage initialized on root path" << path); +} + +void SimpleFileStorage::insert(const char* data, r_Bytes size, int BlobId) throw (r_Error) +{ + ENTER("SimpleFileStorage::insert with BlobID="< path; + getPath(BlobId, &path); + string file_path = path[0]; // Root path + // Iterate trough the levels and create all directories needed. + for (int i = 1; i < path.size() - 1; ++i) + { + file_path += '/' + path[i]; + struct stat status; + if (!stat(file_path.c_str(), &status)) + if (!mkdir(file_path.c_str(), 0770)) + throw 2; // Cannot create directory + } + file_path += '/' + path[path.size() - 1]; + int fd = open(file_path.c_str(), O_CREAT | O_WRONLY, 0770); + if (fd < 0) + throw 3; // Cannot create file + int offset = 0; + // Send the data to the disk + while (offset < size) { + int count = write(fd, data + offset, size - offset); + if (count == -1) + throw 4; // Error while writing data to the disk + offset += count; + } + if (close(fd)<0) + throw 4; // Error while writing data to the disk + LEAVE("SimpleFileStorage::insert"); +} + +void SimpleFileStorage::update(const char* data, r_Bytes size, int BlobId) throw (r_Error) +{ + ENTER("SimpleFileStorage::update"); + vector path; + getPath(BlobId, &path); + string file_path = path[0]; // Root path + // Iterate trough the levels and create all directories needed. + for (int i = 1; i < path.size() - 1; ++i) + { + file_path += '/' + path[i]; + struct stat status; + if (!stat(file_path.c_str(), &status)) + if (!mkdir(file_path.c_str(), 0770)) + throw 2; // Cannot create directory + } + file_path += '/' + path[path.size() - 1]; + + int fd = open(file_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC); + if (fd < 0) + throw 6; // Cannot open file + int offset = 0; + // Send the data to the disk + while (offset < size) { + int count = write(fd, data + offset, size - offset); + if (count == -1) + throw 4; // Error while writing data to the disk + offset += count; + } + if (close(fd)<0) + throw 4; // Error while writing data to the disk + LEAVE("SimpleFileStorage::update"); +} + +void SimpleFileStorage::retrieve(int BlobId, char** data, r_Bytes* size) throw (r_Error) +{ + ENTER("SimpleFileStorage::read"); + string path; + getPath(BlobId, &path); + struct stat status; + if (stat(path.c_str(), &status) < 0) + throw 5; // File does not exist, the blob does not exist. + + *size = status.st_size; + *data = (char*)malloc(status.st_size); + + int fd = open(path.c_str(), O_RDONLY); + if (fd < 0) + throw 6; // Cannot open file + int offset = 0; + // Send the data to the disk + while (offset < *size) { + int count = read(fd, *data + offset, *size - offset); + if (count == -1) + throw 7; // Error while reading data from the disk + offset += count; + } + if (close(fd) < 0) + throw 7; // Error while reading data from the disk + LEAVE("SimpleFileStorage::read"); +} + +void SimpleFileStorage::remove(int BlobId) throw (r_Error) +{ + ENTER("SimpleFileStorage::remove"); + string path; + getPath(BlobId, &path); + if (unlink(path.c_str()) < 0) + throw 8; // Error while removing the file + LEAVE("SimpleFileStorage::remove"); +} + +void SimpleFileStorage::getPath(int BlobId, vector *path) { + ENTER("SimpleFileStorage::getPath"); + path->clear(); + path->push_back(root_path); + stringstream aux; + aux << BlobId; + path->push_back(aux.str()); + LEAVE("SimpleFileStorage::getPath"); +} + +void SimpleFileStorage::getPath(int BlobId, string *path) { + vector segments; + getPath(BlobId, &segments); + *path = segments[0]; + for (int i = 1; i < segments.size(); ++i) + *path += '/' + segments[i]; +} -- cgit