Sleds/cppcore/component/storagenodedbaccess.cpp

999 lines
33 KiB
C++

//
// storagenodedbaccess.cpp
//
// Created by Frank Vernon on 3/20/14.
// Copyright (c) 2014 IOnU. All rights reserved.
// Copyright (c) 2016, Sequence Logic, Inc. All rights reserved.
//
#include "storagenodedbaccess.h"
#include "storagenodedbaccess_java.h"
#include "../cppcoreobjects/cloudguardurn.h"
#include "../cppcoreobjects/permissions.h"
#include "eyetime.h"
#include "eyelog.h"
#include "eyeutils.h"
#include <algorithm>
#include <iostream>
#include <string>
using namespace sequencelogic;
/**
SQLite3 routine to extract a value from JSON.
This is presently limted to elements at the root level of the JSON object.
Non-scalar values are returned as BLOBs in JSON format. You could presumably call this again
with that result until you get to the scalar value you want.
The routine expects two arguments: key, and json. Both as text.
*/
#ifndef WIN32
static void value_from_json(sqlite3_context * context, int argc, sqlite3_value ** argv) __attribute__ ((unused));
#endif
static void value_from_json(sqlite3_context * context, int argc, sqlite3_value ** argv)
{
//check we have what we need
if (argc != 2 ||
sqlite3_value_type(argv[0]) == SQLITE_NULL ||
sqlite3_value_type(argv[1]) == SQLITE_NULL)
{
sqlite3_result_null(context);
}
sequencelogic::JSONObject parser(reinterpret_cast<const char *>(sqlite3_value_text(argv[1])));
sequencelogic::JSONObject value = parser.getJSONObject(reinterpret_cast<const char *>(sqlite3_value_text(argv[0])));
switch (value.gettype()) {
case T_JSON::J_NUMBER:
sqlite3_result_double(context, value.getdouble());
break;
case T_JSON::J_STRING: {
const std::string result = value.getstring();
char * returnValue = (char *)sqlite3_malloc((int)result.length());
memcpy(returnValue, result.c_str(), result.length());
sqlite3_result_text(context, result.c_str(), (int)result.length(), sqlite3_free);
}
break;
case T_JSON::J_BOOLEAN:
sqlite3_result_int(context, value.getboolean() ? 1 : 0);
break;
case T_JSON::J_OBJECT:
case T_JSON::J_ARRAY: {
const std::string result = value.toString();
char * returnValue = (char *)sqlite3_malloc((int)result.length());
memcpy(returnValue, result.c_str(), result.length());
sqlite3_result_blob(context, result.c_str(), (int)result.length(), sqlite3_free);
}
break;
case T_JSON::J_NULL:
default:
sqlite3_result_null(context);
break;
}
}
namespace sequencelogic {
//#pragma mark - StorageNodeDBAccess
StorageNodeDBAccess::StorageNodeDBAccess()
:EyeDB(), _tableInitialized(false)
{
}
//NOTE: This method will also be responsible for migrating database changes as necessary.
bool
StorageNodeDBAccess::initDB(const std::string & dbFilePath)
{
std::lock_guard<std::mutex> lock(_protectInit);
_tableInitialized = false;
if (!EyeDB::open(dbFilePath.c_str())) {
return false;
}
static std::string const tableQuery =
"create table if not exists 'storageguard' ( \
'urn' TEXT, \
'mount' TEXT, \
'signature' TEXT, \
'path' TEXT, \
'parent' TEXT, \
'mime_type' TEXT, \
'nodeJSON' BLOB, \
'metadata_utime' INTEGER, \
'metadata_status' INTEGER, \
'permission_status' INTEGER, \
UNIQUE (urn) on conflict replace)";
//determine existing table matches table hash
std::string digest(DigestMessage("sha1", (const unsigned char *)tableQuery.c_str(), tableQuery.length()));
if (getTableHash() != digest) {
IONUWARN("StorageNodeDBAccess::initDB Drop \'storageguard\' table based on digest change.\n");
executeQuery("drop table if exists 'storageguard'");
if (executeQuery(tableQuery)) {
setTableHash(digest);
}
}
_tableInitialized = getTableHash() == digest;
return _tableInitialized;
}
StorageNodeVector
StorageNodeDBAccess::getNodes(const StorageNode & node)
{
StorageNodeVector result;
// try a partial match
static std::string const query =
"select * from storageguard where \
mount like ? \
and signature like ? \
and path like ? \
";
//get query parameter or convert to wildcard if nil
std::string mount = makeSQLWildcardIfNecessary(node.getMount());
std::string signature = makeSQLWildcardIfNecessary(node.getSignature());
std::string path = makeSQLWildcardIfNecessary(node.getPath());
if (path != "%")
{
path = replaceFilesystemWildcard(path);
}
uint16_t bindPos = 0;
statement statement(*this, query);
if (statement.isPrepared() &&
statement.bind(++bindPos, mount) &&
statement.bind(++bindPos, signature) &&
statement.bind(++bindPos, path))
{
MAP_VECTOR nodes = fetchResults(statement);
for (STRING_STRING_MAP & node : nodes) {
result.push_back(StorageNodePtr(new StorageNode(node["nodeJSON"])));
}
}
return result;
}
StorageNodeVector
StorageNodeDBAccess::getNodesInDirectory(const StorageNode & node)
{
//Get nodes for parent
static std::string const query =
"select * from storageguard where \
mount is ? \
and signature is ? \
and parent is ? \
";
StorageNodeVector result;
std::string mount = makeSQLWildcardIfNecessary(node.getMount());
std::string signature = makeSQLWildcardIfNecessary(node.getSignature());
std::string parent = node.getURN();
uint16_t bindPos = 0;
statement statement(*this, query);
if (statement.isPrepared() &&
statement.bind(++bindPos, mount) &&
statement.bind(++bindPos, signature) &&
statement.bind(++bindPos, parent))
{
MAP_VECTOR nodes = fetchResults(statement);
for (STRING_STRING_MAP & node : nodes) {
result.push_back(StorageNodePtr(new StorageNode(node["nodeJSON"])));
}
}
return result;
}
StorageNodeVector
StorageNodeDBAccess::getNodesByPath(const StorageNode & node)
{
StorageNodeVector result;
std::string path = node.getPath();
if (!path.empty()) {
static std::string const query = "select * from storageguard where path like ?";
path = makeSQLWildcardIfNecessary(node.getPath());
if (path != "%")
{
path = replaceFilesystemWildcard(path);
}
statement statement(*this, query);
if (statement.isPrepared() &&
statement.bind(1, path))
{
MAP_VECTOR nodes = fetchResults(statement);
//this should only be a single result but we'll do this just in case
// the upstream consumer might want to interrogate the result to figure out
// what is going on.
for (STRING_STRING_MAP & node : nodes) {
result.push_back(StorageNodePtr(new StorageNode(node["nodeJSON"])));
}
}
}
return result;
}
StorageNodeVector
StorageNodeDBAccess::getNodesByPathForMountAndSignature(const StorageNode & node)
{
StorageNodeVector result;
static std::string const query = "select * from storageguard where mount like ? and signature like ? and path like ?";
std::string mount = makeSQLWildcardIfNecessary(node.getMount());
std::string signature = makeSQLWildcardIfNecessary(node.getSignature());
std::string path = makeSQLWildcardIfNecessary(node.getPath());
if (path != "%")
{
path = replaceFilesystemWildcard(path);
}
uint16_t bindPos = 0;
statement statement(*this, query);
if (statement.isPrepared() &&
statement.bind(++bindPos, mount) &&
statement.bind(++bindPos, signature) &&
statement.bind(++bindPos, path))
{
MAP_VECTOR nodes = fetchResults(statement);
//this should only be a single result but we'll do this just in case
// the upstream consumer might want to interrogate the result to figure out
// what is going on.
for (STRING_STRING_MAP & node : nodes) {
result.push_back(StorageNodePtr(new StorageNode(node["nodeJSON"])));
}
}
return result;
}
StorageNodeVector
StorageNodeDBAccess::getNodesByStatus(const StorageNode & node)
{
StorageNodeVector result;
// Finding deleted nodes is a common use case; deleted files can not be discovered
// using the local file system
static std::string const query =
"select * from storageguard where \
mount like ? \
and metadata_status like ? \
and signature like ? \
and path like ? \
";
//get query parameter or convert to wildcard if nil
std::string mount = makeSQLWildcardIfNecessary(node.getMount());
int metadata_status = (int) node.getStatus();
std::string signature = makeSQLWildcardIfNecessary(node.getSignature());
std::string path = makeSQLWildcardIfNecessary(node.getPath());
if (path != "%")
{
path = replaceFilesystemWildcard(path);
}
uint16_t bindPos = 0;
statement statement(*this, query);
if (statement.isPrepared() &&
statement.bind(++bindPos, mount) &&
statement.bind(++bindPos, metadata_status) &&
statement.bind(++bindPos, signature) &&
statement.bind(++bindPos, path))
{
MAP_VECTOR nodes = fetchResults(statement);
for (STRING_STRING_MAP & node : nodes) {
result.push_back(StorageNodePtr(new StorageNode(node["nodeJSON"])));
}
}
return result;
}
StorageNodeVector
StorageNodeDBAccess::getNodesByUniformResourceName(const StorageNode & node)
{
StorageNodeVector result;
std::string urn = node.getURN();
if (!urn.empty()) {
static std::string const query = "select * from storageguard where urn is ?";
statement statement(*this, query);
if (statement.isPrepared() &&
statement.bind(1, urn))
{
MAP_VECTOR nodes = fetchResults(statement);
//this should only be a single result but we'll do this just in case
// the upstream consumer might want to interrogate the result to figure out
// what is going on.
for (STRING_STRING_MAP & node : nodes) {
result.push_back(StorageNodePtr(new StorageNode(node["nodeJSON"])));
}
}
}
return result;
}
bool
StorageNodeDBAccess::replaceNode(const StorageNode & node) {
//prepare statement
static std::string const query = "replace into storageguard (urn, mount, signature, path, parent, mime_type, nodeJSON, metadata_utime, metadata_status, permission_status) values (?,?,?,?,?,?,?,?,?,?)";
statement statement(*this, query);
std::string urn = node.getURN();
std::string mount = node.getMount();
std::string signature = node.getSignature();
std::string path = node.getPath();
std::string parent = node.getParent();
std::string mimeType = node.getMimeType();
int status = node.getStatus();
int permStatus = node.getInt(SGDB_PERM_STATUS);
sqlite3_int64 utime = node.getutime().GetTimeMs();
std::string nodeJSON = node.toString();
if (urn.length() == 0) {
std::cout << "Bad document URN in database insert." << std::endl;
}
uint16_t bindPos = 0;
if (statement.isPrepared() &&
statement.bind(++bindPos, urn) &&
statement.bind(++bindPos, mount) &&
statement.bind(++bindPos, signature) &&
statement.bind(++bindPos, path) &&
statement.bind(++bindPos, parent) &&
statement.bind(++bindPos, mimeType) &&
statement.bind(++bindPos, (const void*)nodeJSON.data(), (int)nodeJSON.length()) &&
statement.bind(++bindPos, utime) &&
statement.bind(++bindPos, status) &&
statement.bind(++bindPos, permStatus))
{
int result = statement.step();
if (result != SQLITE_DONE) {
IONUDEBUG("StorageNodeDBAccess::putNode() - sqlite3_step failed %d", result);
return false;
}
} else {
return false;
}
return true;
}
bool
StorageNodeDBAccess::putNode(const StorageNode & node)
{
transaction transaction(*this);
//add children as necessary
StorageNodeVector children = node.getChildren();
if (children.size() > 0) {
for (StorageNodePtr & child : children) {
if (!putNode(*child)) {
return false;
}
}
}
//insert node
else if (!replaceNode(node)) {
return false;
}
transaction.commit();
return true;
}
bool
StorageNodeDBAccess::deleteNodes(const StorageNode & node)
{
transaction transaction(*this);
//do children first
StorageNodeVector children = node.getChildren();
for (StorageNodePtr & child : children) {
if (!deleteNodes(*child)) {
return false;
}
}
//delete the node, prefer urn if specified
std::string urn = node.getURN();
if (!urn.empty() && CloudGuardURN(urn).getType() == CloudGuardURN::PMO_DEVICE_DOCUMENT) {
static std::string const query = "delete from storageguard where urn is ?";
statement statement(*this, query);
if (statement.isPrepared() && statement.bind(1, urn))
{
int result = statement.step();
if (result != SQLITE_DONE) {
IONUDEBUG("StorageNodeDBAccess::deleteNodes() - sqlite3_step failed %d", result);
return false;
}
}
else {
return false;
}
}
else {
static std::string const query =
"delete from storageguard where \
mount like ? \
and signature like ? \
and path like ? \
";
//get query parameter or convert to wildcard if nil
std::string mount = makeSQLWildcardIfNecessary(node.getMount());
std::string signature = makeSQLWildcardIfNecessary(node.getSignature());
std::string path = makeSQLWildcardIfNecessary(node.getPath());
if (path != "%")
{
path = replaceFilesystemWildcard(path);
}
uint16_t bindPos = 0;
statement statement(*this, query);
if (statement.isPrepared() &&
statement.bind(++bindPos, mount) &&
statement.bind(++bindPos, signature) &&
statement.bind(++bindPos, path))
{
int result = statement.step();
if (result != SQLITE_DONE) {
IONUDEBUG("StorageNodeDBAccess::deleteNodes() - sqlite3_step failed %d", result);
return false;
}
}
else {
return false;
}
}
transaction.commit();
return true;
}
StorageNodePtr
StorageNodeDBAccess::listChildren(const StorageNode & parent,
const StorageNode & startingNode,
int32_t limit,
const std::string & sort,
bool sortAscending)
{
std::string parentURN = parent.getURN();
std::string startingNodeURN = startingNode.getURN();
if (parentURN.empty() ||
startingNodeURN.empty())
{
return nullptr;
}
std::string query = "select * from storageguard where parent is ?";
sequencelogic::StorageNodeStatus status = parent.getStatus();
bool haveStatus = false;
if (status != sequencelogic::StorageNodeStatus::unknown) {
query += " and metadata_status is ?";
haveStatus = true;
}
int permStatus = parent.getInt(SGDB_PERM_STATUS);
bool havePermStatus = false;
if (permStatus != 0) {
query += " and permission_status is ?";
havePermStatus = true;
}
//special case utime sort
//this may need to be extended to other columns
bool haveOffset = false;
bool haveLimit = false;
if (sort == "metadata_utime") {
query += " and metadata_utime";
query += sortAscending ? " >" : " <";
query += " (select metadata_utime from storageguard where urn is ?) order by metadata_utime";
query += sortAscending ? " ASC" : " DESC";
haveOffset = true;
//Do limit in the query in the simple case
if (limit > 0) {
haveLimit = true;
query += " LIMIT ";
std::stringstream limitStr;
limitStr << limit;
query += limitStr.str();
}
}
//prepare and execute statement
int bindPos = 0;
statement statement(*this, query);
if (statement.bind(++bindPos, parentURN))
{
//bind status if necessary
if (haveStatus) {
statement.bind(++bindPos, status);
}
if (havePermStatus) {
statement.bind(++bindPos, havePermStatus);
}
//bind offset if necessary
if (haveOffset) {
statement.bind(++bindPos, startingNodeURN);
}
MAP_VECTOR nodes = fetchResults(statement);
//sort
if (sort.length() > 0 && sort != "metadata_utime") {
MapVectorSortFunctor sorter(sort, sortAscending);
std::sort(nodes.begin(), nodes.end(), sorter);
}
//offset
if (!haveOffset) {
//ugly... have to walk array to find our starting point
MapVectorFindFunctor finder("urn", startingNodeURN);
MAP_VECTOR::iterator node_offset = std::find_if(nodes.begin(), nodes.end(), finder);
if (node_offset != nodes.end()) {
nodes.erase(nodes.begin(), node_offset);
}
}
//limit
if (!haveLimit && nodes.size() > (MAP_VECTOR::size_type)abs(limit)) {
if (limit > 0) {
nodes.erase(nodes.begin()+abs(limit), nodes.end());
}
else if (limit < 0)
{
nodes.erase(nodes.begin(), nodes.end()-abs(limit));
}
}
//create result...
StorageNodePtr result = StorageNodePtr(new StorageNode(parent));
StorageNodeVector children;
for (STRING_STRING_MAP & node : nodes) {
children.push_back(StorageNodePtr(new StorageNode(node["nodeJSON"])));
}
result->setChildren(children);
return result;
}
return nullptr;
}
StorageNodePtr
StorageNodeDBAccess::listChildren(const StorageNode & parent,
int32_t offset,
int32_t limit,
const std::string & sort,
bool sortAscending)
{
std::string parentURN = parent.getURN();
if (parentURN.empty()) {
return nullptr;
}
std::string query = "select * from storageguard where parent is ?";
sequencelogic::StorageNodeStatus status = parent.getStatus();
bool haveStatus = false;
if (status != sequencelogic::StorageNodeStatus::unknown) {
query += " and metadata_status is ?";
haveStatus = true;
}
int permStatus = parent.getInt(SGDB_PERM_STATUS);
bool havePermStatus = false;
if (permStatus != 0) {
query += " and permission_status is ?";
havePermStatus = true;
}
//special case utime sort
//this may need to be extended to other columns
bool haveOffset = false;
bool haveLimit = false;
if (sort == "metadata_utime") {
query += " order by metadata_utime";
query += sortAscending ? " ASC" : " DESC";
//Do the offset and limit in the query in the simple case
// ...the other cases make my head hurt
if (limit > 0) {
haveLimit = true;
query += " LIMIT ";
std::stringstream limitStr;
limitStr << limit;
query += limitStr.str();
}
if (offset > 0) {
haveOffset = true;
query += " OFFSET ";
std::stringstream offsetStr;
offsetStr << offset;
query += offsetStr.str();
}
}
//prepare and execute statement
int bindPos = 0;
statement statement(*this, query);
if (statement.bind(++bindPos, parentURN))
{
//bind status if necessary
if (haveStatus) {
statement.bind(++bindPos, status);
}
if (havePermStatus) {
statement.bind(++bindPos, permStatus);
}
MAP_VECTOR nodes = fetchResults(statement);
//sort
if (sort.length() > 0 && sort != "metadata_utime") {
MapVectorSortFunctor sorter(sort, sortAscending);
std::sort(nodes.begin(), nodes.end(), sorter);
}
//offset
if (!haveOffset) {
if (nodes.size() >= static_cast<size_t>(abs(offset))) {
if (offset > 0) {
nodes.erase(nodes.begin(), nodes.begin()+abs(offset));
}
else if (offset < 0) {
nodes.erase(nodes.begin(), nodes.end()-abs(offset));
}
} else if (abs(offset) > 0) {
nodes.erase(nodes.begin(), nodes.end());
}
}
//limit
if (!haveLimit && nodes.size() > (MAP_VECTOR::size_type)abs(limit)) {
if (limit > 0) {
nodes.erase(nodes.begin()+abs(limit), nodes.end());
}
else if (limit < 0)
{
nodes.erase(nodes.begin(), nodes.end()-abs(limit));
}
}
//create result...
StorageNodePtr result = StorageNodePtr(new StorageNode(parent));
StorageNodeVector children;
for (STRING_STRING_MAP & node : nodes) {
children.push_back(StorageNodePtr(new StorageNode(node["nodeJSON"])));
}
result->setChildren(children);
return result;
}
return nullptr;
}
int32_t
StorageNodeDBAccess::countChildren(const StorageNode & parent)
{
std::string parentURN = parent.getURN();
if (parentURN.empty()) {
return 0;
}
std::string query = "select count(*) as rows from storageguard where parent is ? ";
sequencelogic::StorageNodeStatus status = parent.getStatus();
bool haveStatus = false;
if (status != sequencelogic::StorageNodeStatus::unknown) {
query += " and metadata_status is ?";
haveStatus = true;
}
int permStatus = parent.getInt(SGDB_PERM_STATUS);
bool havePermStatus = false;
if (permStatus != 0) {
query += " and permission_status is ?";
havePermStatus = true;
}
statement statement(*this, query);
int bindPos = 0;
if (statement.bind(++bindPos, parentURN))
{
//bind status if necessary
if (haveStatus) {
statement.bind(++bindPos, status);
}
if (havePermStatus) {
statement.bind(++bindPos, permStatus);
}
MAP_VECTOR nodes = fetchResults(statement);
std::string resultString = nodes[0]["rows"];
return (int32_t)std::atol(resultString.c_str());
}
return 0;
}
int32_t
StorageNodeDBAccess::rowCount()
{
int32_t result = -1;
static std::string const query = "select count(*) as rows from storageguard";
statement queryStatement(*this, query);
if (queryStatement.isPrepared()) {
MAP_VECTOR nodes = fetchResults(queryStatement);
std::string resultString = nodes[0]["rows"];
result = (int32_t)std::atol(resultString.c_str());
}
return result;
}
//#pragma mark - Utilities
std::string
StorageNodeDBAccess::getTableHash()
{
std::string tableHash;
static std::string const query = "select hash from version";
statement queryStatement(*this, query);
if (queryStatement.isPrepared()) {
MAP_VECTOR result = fetchResults(queryStatement);
if (result.size() > 0) {
tableHash = result[0]["hash"];
}
}
return tableHash;
}
bool
StorageNodeDBAccess::setTableHash(const std::string & tableHash)
{
static std::string const versionTable = "create table if not exists 'version' (hash)";
if (executeQuery(versionTable)) {
static std::string const clearTableQuery = "delete from version";
executeQuery(clearTableQuery);
static std::string const updateTableQuery = "insert into version values (?)";
statement updateStatement(*this, updateTableQuery);
updateStatement.bind(1, tableHash);
int result = updateStatement.step();
return result == SQLITE_DONE;
}
return false;
}
//might promote this to the EyeDB class, could be generally useful
std::string
StorageNodeDBAccess::makeSQLWildcardIfNecessary(const std::string & string)
{
if (string.length() == 0) {
return "%";
}
return string;
}
std::string
StorageNodeDBAccess::replaceFilesystemWildcard(const std::string & string)
{
std::string result(string);
// escape existing wildcard characters presuming they are
// expected parts of the filesystem query
ReplaceStringInSitu(result, "%", "\\%");
ReplaceStringInSitu(result, "?", "\\?");
#ifdef WIN32
// replace windows directory wildcard
// do this before * substitution below to avoid conflicts
ReplaceStringInSitu(result, "**", "%");
#endif
// replace all multi char matches
std::replace(result.begin(), result.end(), '*', '%');
// replace all single char matches
std::replace(result.begin(), result.end(), '?', '_');
// character set notation should be the same
return result;
}
//#pragma mark - StorageNodeDBAccessJava
StorageNodeDBAccessJava::StorageNodeDBAccessJava()
{
}
StorageNodeDBAccessJava::~StorageNodeDBAccessJava()
{
}
bool
StorageNodeDBAccessJava::initDB(const std::string & dbFilePath)
{
return dbAccess.initDB(dbFilePath);
}
StorageNodeDBAccessJava::STRING_VECTOR_PTR
StorageNodeDBAccessJava::getNodes(const std::string & nodeJSON)
{
StorageNode node(nodeJSON);
StorageNodeVector nodes = dbAccess.getNodes(node);
STRING_VECTOR_PTR result(new STRING_VECTOR);
for (const StorageNode resultNode : nodes) {
result->push_back(resultNode.toString());
}
return result;
}
std::string
StorageNodeDBAccessJava::listChildren(const std::string & parentJSON,
const std::string & startingNodeJSON,
int32_t limit,
const std::string & sort,
bool sortAscending)
{
StorageNode node(parentJSON);
StorageNode startingNode(startingNodeJSON);
StorageNodePtr result = dbAccess.listChildren(node, startingNode, limit, sort, sortAscending);
if (result != nullptr) {
return result->toString();
} else {
return "";
}
}
std::string
StorageNodeDBAccessJava::listChildren(const std::string & parentJSON,
int32_t offset,
int32_t limit,
const std::string & sort,
bool sortAscending)
{
StorageNode node(parentJSON);
StorageNodePtr result = dbAccess.listChildren(node, offset, limit, sort, sortAscending);
if (result != nullptr) {
return result->toString();
} else {
return "";
}
}
bool
StorageNodeDBAccessJava::putNode(const std::string & nodeJSON)
{
StorageNode node(nodeJSON);
return dbAccess.putNode(node);
}
int
StorageNodeDBAccessJava::rowCount()
{
return dbAccess.rowCount();
}
int
StorageNodeDBAccessJava::countChildren(const std::string & parent)
{
StorageNode node(parent);
return dbAccess.countChildren(node);
}
StorageNodeDBAccessJava::STRING_VECTOR_PTR
StorageNodeDBAccessJava::getNodesInDirectory(const std::string & nodeJSON)
{
StorageNode node(nodeJSON);
StorageNodeVector nodeVec = dbAccess.getNodesInDirectory(node);
STRING_VECTOR_PTR result(new STRING_VECTOR);
for (const StorageNode resultNode : nodeVec)
result->push_back(resultNode.toString());
return result;
}
StorageNodeDBAccessJava::STRING_VECTOR_PTR
StorageNodeDBAccessJava::getNodesByPath(const std::string & nodeJSON)
{
StorageNode node(nodeJSON);
StorageNodeVector nodeVec = dbAccess.getNodesByPath(node);
STRING_VECTOR_PTR result(new STRING_VECTOR);
for (const StorageNode resultNode : nodeVec)
result->push_back(resultNode.toString());
return result;
}
StorageNodeDBAccessJava::STRING_VECTOR_PTR
StorageNodeDBAccessJava::getNodesByPathForMountAndSignature(const std::string & nodeJSON)
{
StorageNode node(nodeJSON);
StorageNodeVector nodeVec = dbAccess.getNodesByPathForMountAndSignature(node);
STRING_VECTOR_PTR result(new STRING_VECTOR);
for (const StorageNode resultNode : nodeVec)
result->push_back(resultNode.toString());
return result;
}
StorageNodeDBAccessJava::STRING_VECTOR_PTR
StorageNodeDBAccessJava::getNodesByStatus(const std::string & nodeJSON)
{
StorageNode node(nodeJSON);
StorageNodeVector nodeVec = dbAccess.getNodesByStatus(node);
STRING_VECTOR_PTR result(new STRING_VECTOR);
for (const StorageNode resultNode : nodeVec)
result->push_back(resultNode.toString());
return result;
}
StorageNodeDBAccessJava::STRING_VECTOR_PTR
StorageNodeDBAccessJava::getNodesByUniformResourceName(const std::string & nodeJSON)
{
StorageNode node(nodeJSON);
StorageNodeVector nodeVec = dbAccess.getNodesByUniformResourceName(node);
STRING_VECTOR_PTR result(new STRING_VECTOR);
for (const StorageNode resultNode : nodeVec)
result->push_back(resultNode.toString());
return result;
}
bool
StorageNodeDBAccessJava::deleteNodes(const std::string & nodeJSON)
{
StorageNode node(nodeJSON);
return dbAccess.deleteNodes(node);
}
}