[core] Storage.hpp as facade for core.

This commit is contained in:
d-kunin 2013-08-05 12:47:24 +03:00
parent 8f89d40423
commit e0e098a178
14 changed files with 189 additions and 65 deletions

View file

@ -1,6 +0,0 @@
#pragma once
class Article
{
};

28
storage/article_info.hpp Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#include "storage_common.hpp"
#include <iostream>
struct ArticleInfo
{
ArticleInfo() {}
ArticleInfo(string const & url, string const & title, string const & thumbnailUrl)
: m_url(url), m_title(title), m_thumbnailUrl(thumbnailUrl) {}
string m_url;
string m_title;
string m_thumbnailUrl;
};
inline bool operator == (ArticleInfo const & a1, ArticleInfo const & a2)
{
return a1.m_url == a2.m_url && a1.m_title == a2.m_title && a1.m_thumbnailUrl == a2.m_thumbnailUrl;
}
// It's important that PrintTo() is defined in the SAME
// namespace that defines Bar. C++'s look-up rules rely on that.
inline void PrintTo(ArticleInfo const & artInfo, ::std::ostream* os) {
*os << "ArticleInfi {" << artInfo.m_url << ", "
<< artInfo.m_title << ", "
<< artInfo.m_thumbnailUrl << "}";
}

View file

@ -0,0 +1,25 @@
#include "article_info_storage.hpp"
bool ArticleInfoStorageMock::GetArticleInfoById(ArticleInfo & out, ArticleInfoId const & id)
{
if (id > 2)
return false;
out.m_thumbnailUrl = "stub_url.png";
switch (id)
{
case 0:
out.m_url = "London";
out.m_title = "London";
return true;
case 1:
out.m_url = "Lancaster";
out.m_title = "Lancaster";
return true;
case 2:
out.m_url = "Great_Britain";
out.m_title = "Great Britain";
return true;
}
return false;
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "../std/string.hpp"
#include "article_info.hpp"
#include "storage_common.hpp"
class ArticleInfoStorage
{
public:
virtual ~ArticleInfoStorage() {}
virtual bool GetArticleInfoById(ArticleInfo & out, ArticleInfoId const & id) = 0;
};
class ArticleInfoStorageMock: public ArticleInfoStorage
{
public:
virtual bool GetArticleInfoById(ArticleInfo & out, ArticleInfoId const & id);
};

View file

@ -1,10 +0,0 @@
#include "article_storage.hpp"
bool ArticleStorageMock::GetArticleById(string const & id, Article & out) const
{
ArticleMap::const_iterator it = m_articles.find(id);
if (it == m_articles.end())
return false;
out = it->second;
return true;
}

View file

@ -1,30 +0,0 @@
#pragma once
#include "article.hpp"
#include "../std/map.hpp"
#include "../std/string.hpp"
class ArticleStorage
{
public:
virtual ~ArticleStorage() {}
virtual bool GetArticleById(string const & id, Article & out) const = 0;
};
class ArticleStorageMock : public ArticleStorage
{
public:
ArticleStorageMock(map<string, Article> articles) : m_articles(articles) {}
virtual bool GetArticleById(string const & id, Article & out) const;
private:
typedef map<string, Article> ArticleMap;
ArticleMap m_articles;
};
class ArticleStorageTable : public ArticleStorage
{
public:
virtual bool GetArticleById(string const & id, Article & out) const;
};

15
storage/index_storage.cpp Normal file
View file

@ -0,0 +1,15 @@
#include "index_storage.hpp"
void IndexStorageMock::QueryArticleInfos(vector<ArticleInfoId> & out, string const & prefix,
double /*lat*/, double /*lon*/) const
{
out.clear();
if (prefix.empty())
for (int i = 0; i < 3; ++i)
out.push_back(i);
else if (prefix == "L")
for (int i = 0; i < 2; ++i)
out.push_back(i);
else if (prefix.size() <= 6 && string("London").substr(prefix.size()) == prefix)
out.push_back(1);
}

21
storage/index_storage.hpp Normal file
View file

@ -0,0 +1,21 @@
#pragma once
#include "article_info.hpp"
#include "../std/vector.hpp"
#include "../std/string.hpp"
class IndexStorage
{
public:
virtual ~IndexStorage() {}
virtual void QueryArticleInfos(vector<ArticleInfoId> & out, string const & prefix,
double lat = INVALID_LAT, double lon = INVALID_LON) const = 0;
};
class IndexStorageMock : public IndexStorage
{
public:
virtual void QueryArticleInfos(vector<ArticleInfoId> & out, string const & prefix,
double lat = INVALID_LAT, double lon = INVALID_LON) const;
};

21
storage/storage.cpp Normal file
View file

@ -0,0 +1,21 @@
#include "storage.hpp"
#include "../std/vector.hpp"
Storage::Storage(ArticleInfoStorage * artInfoStorage, IndexStorage * indexStorage)
{
m_articleInfoStorage.reset(artInfoStorage);
m_indexStorage.reset(indexStorage);
}
void Storage::QueryArticleInfos(vector<ArticleInfo> & out, string const & prefix,
double lat, double lon) const
{
vector<ArticleInfoId> ids;
m_indexStorage->QueryArticleInfos(ids, prefix, lat, lon);
out.clear();
out.resize(ids.size());
for (size_t i = 0; i < ids.size(); ++i)
m_articleInfoStorage->GetArticleInfoById(out[i], ids[i]);
}

21
storage/storage.hpp Normal file
View file

@ -0,0 +1,21 @@
# pragma once
#include "article_info_storage.hpp"
#include "index_storage.hpp"
#include "../std/scoped_ptr.hpp"
#include "../std/vector.hpp"
class Storage
{
public:
/// @note takes ownership of @link(ArticleInfoStorage) and @link(IndexStorage)
Storage(ArticleInfoStorage * artInfoStorage, IndexStorage * indexStorage);
void QueryArticleInfos(vector<ArticleInfo> & out, string const & prefix,
double lat = INVALID_LAT, double lon = INVALID_LON) const;
private:
scoped_ptr<ArticleInfoStorage> m_articleInfoStorage;
scoped_ptr<IndexStorage> m_indexStorage;
};

View file

@ -6,14 +6,19 @@ CONFIG -= app_bundle
INCLUDEPATH += ../3rdparty/boost ../3rdparty/googletest/include
HEADERS += \
article.hpp \
article_storage.hpp \
storage.hpp \
article_info_storage.hpp \
article_info.hpp \
index_storage.hpp \
storage_common.hpp \
SOURCES += \
article_storage.cpp
article_info_storage.cpp \
tests/storage_test.cpp \
index_storage.cpp \
storage.cpp \
# unit tests
SOURCES += \
../3rdparty/googletest/src/gtest-all.cc \
../3rdparty/googletest/src/gtest_main.cc \
tests/article_storage_test.cpp \

View file

@ -0,0 +1,9 @@
#pragma once
#include "../std/string.hpp"
#include "../std/stdint.hpp"
typedef uint32_t ArticleInfoId;
#define INVALID_LAT -720.0
#define INVALID_LON -720.0

View file

@ -1,15 +0,0 @@
#include <gtest/gtest.h>
#include "../std/utility.hpp"
#include "../article_storage.hpp"
#include "../std/scoped_ptr.hpp"
TEST(ArticleStorageMock, ReturnsIfAnArticleExists)
{
map<string, Article> articles;
articles.insert(make_pair("SomeId", Article()));
scoped_ptr<ArticleStorage> storage(new ArticleStorageMock(articles));
Article article;
EXPECT_TRUE(storage->GetArticleById("SomeId", article));
EXPECT_FALSE(storage->GetArticleById("SomeIdThatDoesNotExist", article));
}

View file

@ -0,0 +1,22 @@
#include <gtest/gtest.h>
#include "storage.hpp"
#include "article_info_storage.hpp"
#include "index_storage.hpp"
TEST(Storage, Smoke)
{
Storage storage(new ArticleInfoStorageMock(), new IndexStorageMock());
vector<ArticleInfo> artInfos;
storage.QueryArticleInfos(artInfos, "");
ArticleInfo expected[] =
{
ArticleInfo("London", "London", "stub_url.png"),
ArticleInfo("Lancaster", "Lancaster", "stub_url.png"),
ArticleInfo("Great_Britain", "Great Britain", "stub_url.png"),
};
EXPECT_EQ(vector<ArticleInfo>(&expected[0], &expected[0] + 3), artInfos);
}