summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mythfs/etc/icebox.config2
-rw-r--r--mythfs/service/Jamfile.jam7
-rw-r--r--mythfs/service/inodes/abstractDynamicDirectory.cpp22
-rw-r--r--mythfs/service/inodes/abstractDynamicDirectory.h18
-rw-r--r--mythfs/service/inodes/allDirectory.cpp20
-rw-r--r--mythfs/service/inodes/allDirectory.h22
-rw-r--r--mythfs/service/inodes/byDateDirectory.h16
-rw-r--r--mythfs/service/inodes/byTitleDirectory.h15
-rw-r--r--mythfs/service/inodes/file.h15
-rw-r--r--mythfs/service/inodes/groupingDirectory.h17
-rw-r--r--mythfs/service/inodes/node.cpp23
-rw-r--r--mythfs/service/inodes/node.h27
-rw-r--r--mythfs/service/inodes/staticDirectory.cpp34
-rw-r--r--mythfs/service/inodes/staticDirectory.h19
-rw-r--r--mythfs/service/inodes/symlink.cpp25
-rw-r--r--mythfs/service/inodes/symlink.h22
-rw-r--r--mythfs/service/main.cpp24
-rw-r--r--mythfs/service/openDirectory.cpp22
-rw-r--r--mythfs/service/openDirectory.h20
-rw-r--r--mythfs/service/recordingsVolume.cpp36
-rw-r--r--mythfs/service/recordingsVolume.h8
-rw-r--r--mythfs/service/util.h31
-rw-r--r--mythfs/unittests/fixtures/schema-min.sql89
-rw-r--r--mythfs/unittests/mockDefs.cpp9
-rw-r--r--mythfs/unittests/mockDefs.h2
-rw-r--r--mythfs/unittests/testMain.cpp60
-rw-r--r--mythfs/util.h33
27 files changed, 612 insertions, 26 deletions
diff --git a/mythfs/etc/icebox.config b/mythfs/etc/icebox.config
index f7ee191..30fe04b 100644
--- a/mythfs/etc/icebox.config
+++ b/mythfs/etc/icebox.config
@@ -1 +1 @@
-IceBox.Service.MythFS=mythfs:createIceTrayService --MythFS.ThreadPool.Size=2 --MythFS.ThreadPool.SizeMax=10 --mythconverg.Database.ConnectionString="server=mysql user=mythtv database=mythconverg password=mythpass" --GentooBrowseAPI.Endpoints="tcp -p 4001"
+IceBox.Service.MythFS=mythfs:createIceTrayService --MythFS.ThreadPool.Size=2 --MythFS.ThreadPool.SizeMax=10 --MythFS.Database.ConnectionString="server=mysql;user=mythtv;database=mythconverg;password=mythpass" --MythFS.Endpoints="tcp -p 4001"
diff --git a/mythfs/service/Jamfile.jam b/mythfs/service/Jamfile.jam
index 7dc26cb..2a209e1 100644
--- a/mythfs/service/Jamfile.jam
+++ b/mythfs/service/Jamfile.jam
@@ -1,13 +1,15 @@
import icetray ;
+import package ;
lib mythfs :
- [ glob *.cpp *.ice sql/*.sql ]
+ [ glob *.cpp inodes/*.cpp *.ice sql/*.sql ]
:
<slicer>yes
<library>..//netfsComms
<library>..//adhocutil
<library>..//dbppcore
<library>..//boost_system
+ <library>..//boost_filesystem
<library>..//boost_date_time
<library>..//Ice
<library>..//IceBox
@@ -18,9 +20,12 @@ lib mythfs :
<library>..//slicer-db
<library>../..//glibmm
<icetray.sql.namespace>MythFS
+ <include>.
: :
<include>.
<library>..//netfsComms
<library>..//icetray
;
+package.install install : : : mythfs ;
+
diff --git a/mythfs/service/inodes/abstractDynamicDirectory.cpp b/mythfs/service/inodes/abstractDynamicDirectory.cpp
new file mode 100644
index 0000000..0a703db
--- /dev/null
+++ b/mythfs/service/inodes/abstractDynamicDirectory.cpp
@@ -0,0 +1,22 @@
+#include "abstractDynamicDirectory.h"
+#include <sys/stat.h>
+#include <exceptions.h>
+
+namespace MythFS {
+ NetFS::Attr
+ AbstractDynamicDirectory::getattr() const
+ {
+ return {
+ 0, 0,
+ S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH | S_IFDIR,
+ 1, "root", "root", 0, 0, 0, 0, 0, 0, 0
+ };
+ }
+
+ Node::PointerType
+ AbstractDynamicDirectory::getChild(const std::string &) const
+ {
+ throw ::NetFS::SystemError(EINVAL);
+ }
+}
+
diff --git a/mythfs/service/inodes/abstractDynamicDirectory.h b/mythfs/service/inodes/abstractDynamicDirectory.h
new file mode 100644
index 0000000..0d62931
--- /dev/null
+++ b/mythfs/service/inodes/abstractDynamicDirectory.h
@@ -0,0 +1,18 @@
+#ifndef MYTHFS_ABSTRACTDYNAMICDIRECTORY_H
+#define MYTHFS_ABSTRACTDYNAMICDIRECTORY_H
+
+#include "node.h"
+
+namespace MythFS {
+ class AbstractDynamicDirectory : public Node {
+ public:
+ NetFS::Attr getattr() const override;
+
+ protected:
+ virtual PointerType getChild(const std::string &) const override = 0;
+ virtual NetFS::NameList getContents() const override = 0;
+ };
+}
+
+#endif
+
diff --git a/mythfs/service/inodes/allDirectory.cpp b/mythfs/service/inodes/allDirectory.cpp
new file mode 100644
index 0000000..d61b8b9
--- /dev/null
+++ b/mythfs/service/inodes/allDirectory.cpp
@@ -0,0 +1,20 @@
+#include "allDirectory.h"
+#include <util.h>
+#include "symlink.h"
+
+namespace MythFS {
+ AllDirectory::AllDirectory(const DBPrx & d) : db(d) { }
+
+ NetFS::NameList
+ AllDirectory::getContents() const
+ {
+ return db->getRecorded() / &Recorded::basename;
+ }
+
+ Node::PointerType
+ AllDirectory::getChild(const std::string & path) const
+ {
+ return new Symlink("/var/store/mythrecordings/" + path);
+ }
+}
+
diff --git a/mythfs/service/inodes/allDirectory.h b/mythfs/service/inodes/allDirectory.h
new file mode 100644
index 0000000..67165ef
--- /dev/null
+++ b/mythfs/service/inodes/allDirectory.h
@@ -0,0 +1,22 @@
+#ifndef MYTHFS_ALLDIRECTORY_H
+#define MYTHFS_ALLDIRECTORY_H
+
+#include "abstractDynamicDirectory.h"
+#include "myth-db.h"
+
+namespace MythFS {
+ class AllDirectory : public AbstractDynamicDirectory {
+ public:
+ AllDirectory(const DBPrx &);
+
+ protected:
+ NetFS::NameList getContents() const override;
+ PointerType getChild(const std::string &) const override;
+
+ private:
+ DBPrx db;
+ };
+}
+
+#endif
+
diff --git a/mythfs/service/inodes/byDateDirectory.h b/mythfs/service/inodes/byDateDirectory.h
new file mode 100644
index 0000000..945a9d0
--- /dev/null
+++ b/mythfs/service/inodes/byDateDirectory.h
@@ -0,0 +1,16 @@
+#ifndef MYTHFS_BYTITLEDIRECTORY_H
+#define MYTHFS_BYTITLEDIRECTORY_H
+
+#include "groupingDirectory.h"
+
+namespace MythFS {
+ class ByDateDirectory : public GroupingDirectory<std::string> {
+
+ protected:
+ virtual std::string attribute(const MythFS::RecordedPtr &) const;
+ };
+}
+
+#endif
+
+
diff --git a/mythfs/service/inodes/byTitleDirectory.h b/mythfs/service/inodes/byTitleDirectory.h
new file mode 100644
index 0000000..e9883d1
--- /dev/null
+++ b/mythfs/service/inodes/byTitleDirectory.h
@@ -0,0 +1,15 @@
+#ifndef MYTHFS_BYTITLEDIRECTORY_H
+#define MYTHFS_BYTITLEDIRECTORY_H
+
+#include "groupingDirectory.h"
+
+namespace MythFS {
+ class ByTitleDirectory : public GroupingDirectory<std::string> {
+
+ protected:
+ virtual std::string attribute(const MythFS::RecordedPtr &) const;
+ };
+}
+
+#endif
+
diff --git a/mythfs/service/inodes/file.h b/mythfs/service/inodes/file.h
new file mode 100644
index 0000000..e71a343
--- /dev/null
+++ b/mythfs/service/inodes/file.h
@@ -0,0 +1,15 @@
+#ifndef MYTHFS_FILE_H
+#define MYTHFS_FILE_H
+
+#include "node.h"
+
+namespace MythFS {
+ class File : public Node {
+ public:
+ NetFS::Attr getattr() const override;
+ PointerType getChild(const std::string &) const override;
+ };
+}
+
+#endif
+
diff --git a/mythfs/service/inodes/groupingDirectory.h b/mythfs/service/inodes/groupingDirectory.h
new file mode 100644
index 0000000..82b3c0c
--- /dev/null
+++ b/mythfs/service/inodes/groupingDirectory.h
@@ -0,0 +1,17 @@
+#ifndef MYTHFS_GROUPINGDIRECTORY_H
+#define MYTHFS_GROUPINGDIRECTORY_H
+
+#include "abstractDynamicDirectory.h"
+
+namespace MythFS {
+ template <typename T>
+ class GroupingDirectory : public AbstractDynamicDirectory {
+ public:
+ protected:
+ virtual T attribute(const MythFS::RecordedPtr &) const = 0;
+ NetFS::NameList getContents() const override;
+ };
+}
+
+#endif
+
diff --git a/mythfs/service/inodes/node.cpp b/mythfs/service/inodes/node.cpp
new file mode 100644
index 0000000..19e4fd3
--- /dev/null
+++ b/mythfs/service/inodes/node.cpp
@@ -0,0 +1,23 @@
+#include "node.h"
+#include <exceptions.h>
+
+namespace MythFS {
+ Node::PointerType
+ Node::getChild(const std::string &) const
+ {
+ throw ::NetFS::SystemError(ENOTDIR);
+ }
+
+ std::string
+ Node::readlink() const
+ {
+ throw ::NetFS::SystemError(EINVAL);
+ }
+
+ NetFS::NameList
+ Node::getContents() const
+ {
+ throw NetFS::SystemError(ENOTDIR);
+ }
+}
+
diff --git a/mythfs/service/inodes/node.h b/mythfs/service/inodes/node.h
new file mode 100644
index 0000000..b88e403
--- /dev/null
+++ b/mythfs/service/inodes/node.h
@@ -0,0 +1,27 @@
+#ifndef MYTHFS_NODE_H
+#define MYTHFS_NODE_H
+
+#include <map>
+#include <string>
+#include <IceUtil/Handle.h>
+#include <Ice/Object.h>
+#include <types.h>
+
+namespace MythFS {
+ class Node;
+
+ typedef std::map<std::string, IceUtil::Handle<Node>> Contents;
+
+ class Node : public virtual Ice::Object {
+ public:
+ typedef IceUtil::Handle<Node> PointerType;
+
+ virtual NetFS::Attr getattr() const = 0;
+ virtual std::string readlink() const;
+ virtual PointerType getChild(const std::string &) const;
+ virtual NetFS::NameList getContents() const;
+ };
+}
+
+#endif
+
diff --git a/mythfs/service/inodes/staticDirectory.cpp b/mythfs/service/inodes/staticDirectory.cpp
new file mode 100644
index 0000000..31cc4fa
--- /dev/null
+++ b/mythfs/service/inodes/staticDirectory.cpp
@@ -0,0 +1,34 @@
+#include "staticDirectory.h"
+#include <sys/stat.h>
+#include <safeMapFind.h>
+#include <exceptions.h>
+#include <util.h>
+
+namespace MythFS {
+ NetFS::Attr
+ StaticDirectory::getattr() const
+ {
+ return {
+ 0, 0,
+ S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH | S_IFDIR,
+ 1, "root", "root", 0, 0, 0, 0, 0, 0, 0};
+ }
+
+ class NoSuchFileOrDirectory : public ::NetFS::SystemError {
+ public:
+ NoSuchFileOrDirectory(const std::string &) : ::NetFS::SystemError(ENOENT) {}
+ };
+
+ Node::PointerType
+ StaticDirectory::getChild(const std::string & path) const
+ {
+ return AdHoc::safeMapLookup<NoSuchFileOrDirectory>(contents, path);
+ }
+
+ NetFS::NameList
+ StaticDirectory::getContents() const
+ {
+ return contents / &Contents::value_type::first;
+ }
+}
+
diff --git a/mythfs/service/inodes/staticDirectory.h b/mythfs/service/inodes/staticDirectory.h
new file mode 100644
index 0000000..0ebb585
--- /dev/null
+++ b/mythfs/service/inodes/staticDirectory.h
@@ -0,0 +1,19 @@
+#ifndef MYTHFS_STATICDIRECTORY_H
+#define MYTHFS_STATICDIRECTORY_H
+
+#include "node.h"
+
+namespace MythFS {
+ class StaticDirectory : public Node {
+ public:
+ NetFS::Attr getattr() const override;
+ PointerType getChild(const std::string &) const override;
+ NetFS::NameList getContents() const override;
+
+ protected:
+ Contents contents;
+ };
+}
+
+#endif
+
diff --git a/mythfs/service/inodes/symlink.cpp b/mythfs/service/inodes/symlink.cpp
new file mode 100644
index 0000000..8dcc0df
--- /dev/null
+++ b/mythfs/service/inodes/symlink.cpp
@@ -0,0 +1,25 @@
+#include "symlink.h"
+#include <sys/stat.h>
+
+namespace MythFS {
+ Symlink::Symlink(const std::string & t) :
+ target(t)
+ {
+
+ }
+
+ NetFS::Attr
+ Symlink::getattr() const
+ {
+ return {
+ 0, 0,
+ S_IRUSR | S_IRGRP | S_IROTH | S_IFLNK,
+ 1,"root","root",0,0,0,0,0,0,0};
+ }
+
+ std::string
+ Symlink::readlink() const
+ {
+ return target;
+ }
+}
diff --git a/mythfs/service/inodes/symlink.h b/mythfs/service/inodes/symlink.h
new file mode 100644
index 0000000..227d2bd
--- /dev/null
+++ b/mythfs/service/inodes/symlink.h
@@ -0,0 +1,22 @@
+#ifndef MYTHFS_SYMLINK_H
+#define MYTHFS_SYMLINK_H
+
+#include <types.h>
+#include "node.h"
+
+namespace MythFS {
+ class Symlink : public Node {
+ public:
+ Symlink(const std::string &);
+
+ NetFS::Attr getattr() const override;
+ std::string readlink() const override;
+
+ private:
+ const std::string target;
+
+ };
+}
+
+#endif
+
diff --git a/mythfs/service/main.cpp b/mythfs/service/main.cpp
index 145cf71..6aafc7a 100644
--- a/mythfs/service/main.cpp
+++ b/mythfs/service/main.cpp
@@ -5,16 +5,18 @@
#include "recordingsVolume.h"
#include "dbimpl.h"
-class Api : public IceTray::Service {
- public:
- void addObjects(const std::string &, const Ice::CommunicatorPtr & ic, const Ice::StringSeq &, const Ice::ObjectAdapterPtr & adp) override
- {
- auto db = getConnectionPool(ic, "mysql", "mythconverg");
- adp->add(new MythFS::Service(), ic->stringToIdentity("service"));
- adp->add(new MythFS::DBImpl(db), ic->stringToIdentity("db"));
- adp->add(new MythFS::RecordingsVolume(), ic->stringToIdentity("recordings"));
- }
-};
+namespace MythFS {
+ class Api : public IceTray::Service {
+ public:
+ void addObjects(const std::string &, const Ice::CommunicatorPtr & ic, const Ice::StringSeq &, const Ice::ObjectAdapterPtr & adp) override
+ {
+ auto dbpool = getConnectionPool(ic, "mysql", "MythFS");
+ adp->add(new MythFS::Service(), ic->stringToIdentity("Service"));
+ auto dbservice = DBPrx::uncheckedCast(adp->add(new DBImpl(dbpool), ic->stringToIdentity("DB")));
+ adp->add(new RecordingsVolume(dbservice), ic->stringToIdentity("recordings"));
+ }
+ };
-NAMEDFACTORY("default", Api, IceTray::ServiceFactory);
+ NAMEDFACTORY("default", MythFS::Api, IceTray::ServiceFactory);
+}
diff --git a/mythfs/service/openDirectory.cpp b/mythfs/service/openDirectory.cpp
new file mode 100644
index 0000000..42a3e59
--- /dev/null
+++ b/mythfs/service/openDirectory.cpp
@@ -0,0 +1,22 @@
+#include "openDirectory.h"
+#include <Ice/ObjectAdapter.h>
+
+namespace MythFS {
+ OpenDirectory::OpenDirectory(Node::PointerType d) :
+ directory(d)
+ {
+ }
+
+ ::NetFS::NameList
+ OpenDirectory::readdir(const Ice::Current &)
+ {
+ return directory->getContents();
+ }
+
+ void
+ OpenDirectory::close(const Ice::Current & ic)
+ {
+ ic.adapter->remove(ic.id);
+ }
+}
+
diff --git a/mythfs/service/openDirectory.h b/mythfs/service/openDirectory.h
new file mode 100644
index 0000000..40215f5
--- /dev/null
+++ b/mythfs/service/openDirectory.h
@@ -0,0 +1,20 @@
+#ifndef MYTHFS_OPENDIRECTORY_H
+#define MYTHFS_OPENDIRECTORY_H
+
+#include <directory.h>
+#include "inodes/node.h"
+
+namespace MythFS {
+ class OpenDirectory : public ::NetFS::Directory {
+ public:
+ OpenDirectory(Node::PointerType);
+
+ ::NetFS::NameList readdir(const Ice::Current &) override;
+ void close(const Ice::Current &) override;
+ private:
+ Node::PointerType directory;
+ };
+}
+
+#endif
+
diff --git a/mythfs/service/recordingsVolume.cpp b/mythfs/service/recordingsVolume.cpp
index cfebe46..f5bf07b 100644
--- a/mythfs/service/recordingsVolume.cpp
+++ b/mythfs/service/recordingsVolume.cpp
@@ -1,10 +1,21 @@
#include "recordingsVolume.h"
+#include <myth-models.h>
+#include <boost/filesystem/path.hpp>
+
+#include <Ice/ObjectAdapter.h>
+#include "inodes/allDirectory.h"
+#include "openDirectory.h"
namespace MythFS {
+ RecordingsVolume::RecordingsVolume(DBPrx db)
+ {
+ contents.insert({ "all", new AllDirectory(db) });
+ }
+
NetFS::DirectoryPrx
- RecordingsVolume::opendir(const NetFS::ReqEnv &, const std::string &, const Ice::Current&)
+ RecordingsVolume::opendir(const NetFS::ReqEnv &, const std::string & p, const Ice::Current & ic)
{
- return NULL;
+ return ::NetFS::DirectoryPrx::uncheckedCast(ic.adapter->addWithUUID(new OpenDirectory(resolvePath(p))));
}
void RecordingsVolume::mkdir(const NetFS::ReqEnv &, const std::string &, Ice::Int, const Ice::Current&)
{
@@ -48,12 +59,12 @@ namespace MythFS {
Ice::Int RecordingsVolume::access(const NetFS::ReqEnv &, const std::string &, Ice::Int, const Ice::Current&)
{
- throw ::NetFS::SystemError(ENOSYS);
+ return 0;
}
- NetFS::Attr RecordingsVolume::getattr(const NetFS::ReqEnv &, const std::string &, const Ice::Current&)
+ NetFS::Attr RecordingsVolume::getattr(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&)
{
- throw ::NetFS::SystemError(ENOSYS);
+ return resolvePath(path)->getattr();
}
void RecordingsVolume::mknod(const NetFS::ReqEnv &, const std::string &, Ice::Int, Ice::Int, const Ice::Current&)
@@ -76,9 +87,9 @@ namespace MythFS {
throw ::NetFS::SystemError(ENOSYS);
}
- std::string RecordingsVolume::readlink(const NetFS::ReqEnv &, const std::string &, const Ice::Current&)
+ std::string RecordingsVolume::readlink(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&)
{
- throw ::NetFS::SystemError(ENOSYS);
+ return resolvePath(path)->readlink();
}
void RecordingsVolume::chmod(const NetFS::ReqEnv &, const std::string &, Ice::Int, const Ice::Current&)
@@ -99,5 +110,16 @@ namespace MythFS {
void RecordingsVolume::disconnect(const Ice::Current&)
{
}
+
+ Node::PointerType
+ RecordingsVolume::resolvePath(const std::string & p)
+ {
+ Node::PointerType d = this;
+ boost::filesystem::path path(p.substr(1));
+ for (const auto & e : path) {
+ d = d->getChild(e.string());
+ }
+ return d;
+ }
}
diff --git a/mythfs/service/recordingsVolume.h b/mythfs/service/recordingsVolume.h
index 65357ca..4bf227d 100644
--- a/mythfs/service/recordingsVolume.h
+++ b/mythfs/service/recordingsVolume.h
@@ -2,10 +2,14 @@
#define MYTHFS_RECORDINGS_VOLUME_H
#include <volume.h>
+#include "inodes/staticDirectory.h"
+#include <myth-db.h>
namespace MythFS {
- class RecordingsVolume : public ::NetFS::Volume {
+ class RecordingsVolume : public ::NetFS::Volume, public StaticDirectory {
public:
+ RecordingsVolume(DBPrx);
+
virtual NetFS::DirectoryPrx opendir(const NetFS::ReqEnv &, const std::string & path, const Ice::Current&) override;
virtual void mkdir(const NetFS::ReqEnv &, const std::string & path, Ice::Int id, const Ice::Current&) override;
@@ -34,6 +38,8 @@ namespace MythFS {
virtual void disconnect(const Ice::Current&) override;
+ private:
+ Node::PointerType resolvePath(const std::string &);
};
}
diff --git a/mythfs/service/util.h b/mythfs/service/util.h
new file mode 100644
index 0000000..5e42b34
--- /dev/null
+++ b/mythfs/service/util.h
@@ -0,0 +1,31 @@
+#ifndef MYTHFS_UTIL_H
+#define MYTHFS_UTIL_H
+
+#include <vector>
+
+template <typename T, typename MT>
+std::vector<typename std::remove_const<MT>::type>
+operator/(const T & input, MT T::value_type::element_type::* m)
+{
+ std::vector<typename std::remove_const<MT>::type> result;
+ result.reserve(input.size());
+ for (const auto & i : input) {
+ result.push_back(i.get()->*m);
+ }
+ return result;
+}
+
+template <typename T, typename MT>
+std::vector<typename std::remove_const<MT>::type>
+operator/(const T & input, MT T::value_type::* m)
+{
+ std::vector<typename std::remove_const<MT>::type> result;
+ result.reserve(input.size());
+ for (const auto & i : input) {
+ result.push_back(i.*m);
+ }
+ return result;
+}
+
+#endif
+
diff --git a/mythfs/unittests/fixtures/schema-min.sql b/mythfs/unittests/fixtures/schema-min.sql
new file mode 100644
index 0000000..ebf90d9
--- /dev/null
+++ b/mythfs/unittests/fixtures/schema-min.sql
@@ -0,0 +1,89 @@
+-- MySQL dump 10.13 Distrib 5.6.28, for Linux (x86_64)
+--
+-- Host: defiant Database: mythconverg
+-- ------------------------------------------------------
+-- Server version 5.6.27-log
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `recorded`
+--
+
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `recorded` (
+ `chanid` int(10) unsigned NOT NULL DEFAULT '0',
+ `starttime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `endtime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `title` varchar(128) NOT NULL DEFAULT '',
+ `subtitle` varchar(128) NOT NULL DEFAULT '',
+ `description` varchar(16000) NOT NULL DEFAULT '',
+ `season` smallint(5) NOT NULL,
+ `episode` smallint(5) NOT NULL,
+ `category` varchar(64) NOT NULL DEFAULT '',
+ `hostname` varchar(64) NOT NULL DEFAULT '',
+ `bookmark` tinyint(1) NOT NULL DEFAULT '0',
+ `editing` int(10) unsigned NOT NULL DEFAULT '0',
+ `cutlist` tinyint(1) NOT NULL DEFAULT '0',
+ `autoexpire` int(11) NOT NULL DEFAULT '0',
+ `commflagged` int(10) unsigned NOT NULL DEFAULT '0',
+ `recgroup` varchar(32) NOT NULL DEFAULT 'Default',
+ `recordid` int(11) DEFAULT NULL,
+ `seriesid` varchar(64) DEFAULT NULL,
+ `programid` varchar(64) DEFAULT NULL,
+ `inetref` varchar(40) NOT NULL,
+ `lastmodified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `filesize` bigint(20) NOT NULL DEFAULT '0',
+ `stars` float NOT NULL DEFAULT '0',
+ `previouslyshown` tinyint(1) DEFAULT '0',
+ `originalairdate` date DEFAULT NULL,
+ `preserve` tinyint(1) NOT NULL DEFAULT '0',
+ `findid` int(11) NOT NULL DEFAULT '0',
+ `deletepending` tinyint(1) NOT NULL DEFAULT '0',
+ `transcoder` int(11) NOT NULL DEFAULT '0',
+ `timestretch` float NOT NULL DEFAULT '1',
+ `recpriority` int(11) NOT NULL DEFAULT '0',
+ `basename` varchar(255) NOT NULL,
+ `progstart` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `progend` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `playgroup` varchar(32) NOT NULL DEFAULT 'Default',
+ `profile` varchar(32) NOT NULL DEFAULT '',
+ `duplicate` tinyint(1) NOT NULL DEFAULT '0',
+ `transcoded` tinyint(1) NOT NULL DEFAULT '0',
+ `watched` tinyint(4) NOT NULL DEFAULT '0',
+ `storagegroup` varchar(32) NOT NULL DEFAULT 'Default',
+ `bookmarkupdate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`chanid`,`starttime`),
+ UNIQUE KEY `uni_recorded_basename` (`basename`),
+ KEY `endtime` (`endtime`),
+ KEY `seriesid` (`seriesid`),
+ KEY `programid` (`programid`),
+ KEY `title` (`title`),
+ KEY `recordid` (`recordid`),
+ KEY `deletepending` (`deletepending`,`lastmodified`),
+ KEY `recgroup` (`recgroup`,`endtime`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2015-12-24 5:08:30
+
diff --git a/mythfs/unittests/mockDefs.cpp b/mythfs/unittests/mockDefs.cpp
index 68dec08..ba233c3 100644
--- a/mythfs/unittests/mockDefs.cpp
+++ b/mythfs/unittests/mockDefs.cpp
@@ -2,16 +2,17 @@
#include <definedDirs.h>
Service::Service() :
- MySQL::Mock("mythconverg", {
- rootDir / "fixtures" / "schema.sql",
+ MySQL::Mock("MythFS", {
+ //rootDir / "fixtures" / "schema.sql",
+ rootDir / "fixtures" / "schema-min.sql",
rootDir / "fixtures" / "data.sql"
})
{
}
TestClient::TestClient() :
- db(getProxy<MythFS::DBPrx>("db")),
- s(getProxy<NetFS::ServicePrx>("service"))
+ db(getProxy<MythFS::DBPrx>("DB")),
+ s(getProxy<NetFS::ServicePrx>("Service"))
{
}
diff --git a/mythfs/unittests/mockDefs.h b/mythfs/unittests/mockDefs.h
index 0b6248c..b1975e9 100644
--- a/mythfs/unittests/mockDefs.h
+++ b/mythfs/unittests/mockDefs.h
@@ -7,7 +7,7 @@
#include <service.h>
#include <myth-db.h>
-class DLL_PUBLIC Service : public IceTray::DryIce, MySQL::Mock {
+class DLL_PUBLIC Service : MySQL::Mock, public IceTray::DryIce {
public:
Service();
};
diff --git a/mythfs/unittests/testMain.cpp b/mythfs/unittests/testMain.cpp
index 8c18647..5451630 100644
--- a/mythfs/unittests/testMain.cpp
+++ b/mythfs/unittests/testMain.cpp
@@ -4,6 +4,8 @@
#include <Ice/Ice.h>
#include <IceBox/IceBox.h>
#include <service.h>
+#include <volume.h>
+#include <sys/stat.h>
#include "mockDefs.h"
BOOST_GLOBAL_FIXTURE(Service);
@@ -37,3 +39,61 @@ BOOST_AUTO_TEST_CASE( getRecorded )
BOOST_AUTO_TEST_SUITE_END();
+class RecordingsTest : public TestClient {
+ public:
+ RecordingsTest() :
+ rv(s->connect("recordings", std::string()))
+ {
+ re.user = "root";
+ re.grp = "root";
+ }
+ ~RecordingsTest()
+ {
+ rv->disconnect();
+ }
+
+ protected:
+ ::NetFS::ReqEnv re;
+ ::NetFS::VolumePrx rv;
+};
+
+BOOST_FIXTURE_TEST_SUITE(rt, RecordingsTest)
+
+BOOST_AUTO_TEST_CASE( statRoot )
+{
+ auto a = rv->getattr(re, "/");
+ BOOST_REQUIRE(S_ISDIR(a.mode));
+}
+
+BOOST_AUTO_TEST_CASE( listRoot )
+{
+ auto d = rv->opendir(re, "/");
+ auto ls = d->readdir();
+ BOOST_REQUIRE_EQUAL(1, ls.size());
+ BOOST_REQUIRE_EQUAL("all", ls.front());
+ d->close();
+}
+
+BOOST_AUTO_TEST_CASE( statAll )
+{
+ auto a = rv->getattr(re, "/all");
+ BOOST_REQUIRE(S_ISDIR(a.mode));
+}
+
+BOOST_AUTO_TEST_CASE( listAll )
+{
+ auto d = rv->opendir(re, "/all");
+ auto ls = d->readdir();
+ BOOST_REQUIRE_EQUAL(11, ls.size());
+ BOOST_REQUIRE_EQUAL("1001_20151220233900.mpg", ls.front());
+ BOOST_REQUIRE_EQUAL("1303_20151202205900.mpg", ls.back());
+ d->close();
+
+ auto a = rv->getattr(re, "/all/1001_20151220233900.mpg");
+ BOOST_REQUIRE(S_ISLNK(a.mode));
+ auto l = rv->readlink(re, "/all/1001_20151220233900.mpg");
+ BOOST_REQUIRE_EQUAL("/var/store/mythrecordings/1001_20151220233900.mpg", l);
+}
+
+BOOST_AUTO_TEST_SUITE_END();
+
diff --git a/mythfs/util.h b/mythfs/util.h
new file mode 100644
index 0000000..3d7ea35
--- /dev/null
+++ b/mythfs/util.h
@@ -0,0 +1,33 @@
+#ifndef MYTHFS_UTIL_H
+#define MYTHFS_UTIL_H
+
+template <typename T, typename MT>
+std::vector<MT>
+operator/(const T & input, MT T::value_type::* m)
+{
+ std::vector<MT> result;
+ /*
+ result.reserve(input.size());
+ for (const auto & i : input) {
+ result.push_back(i.*m);
+ }
+ */
+ return result;
+}
+
+/*
+template <typename T, typename MT>
+std::vector<std::string>
+operator/(const T & input, MT T::value_type::element_type::* m)
+{
+ std::vector<MT> result;
+ result.reserve(input.size());
+ for (const auto & i : input) {
+ result.push_back(i.get()->*m);
+ }
+ return result;
+}
+*/
+
+#endif
+