Petr Onderka has submitted this change and it was merged.

Change subject: writing different kinds of dumps (stub/pages, current/history)
......................................................................


writing different kinds of dumps (stub/pages, current/history)

Change-Id: Ibdd75afc5133790cef878ffe5a5ea41c83b0da98
---
M CMakeLists.txt
A DumpKind.cpp
A DumpKind.h
M DumpObjects/DumpRevision.cpp
M DumpObjects/DumpTraits.h
M DumpObjects/FileHeader.cpp
M DumpObjects/FileHeader.h
A DumpWriters/ArticlesWriterWrapper.cpp
A DumpWriters/ArticlesWriterWrapper.h
A DumpWriters/CompositeWriter.cpp
A DumpWriters/CompositeWriter.h
A DumpWriters/CurrentWriterWrapper.cpp
A DumpWriters/CurrentWriterWrapper.h
M DumpWriters/DumpWriter.cpp
M DumpWriters/DumpWriter.h
A DumpWriters/IDumpWriter.h
D DumpWriters/PagesHistoryWriter.cpp
D DumpWriters/PagesHistoryWriter.h
D DumpWriters/StubCurrentWriter.cpp
D DumpWriters/StubCurrentWriter.h
D DumpWriters/StubHistoryWriter.cpp
D DumpWriters/StubHistoryWriter.h
A DumpWriters/WriterWrapper.cpp
A DumpWriters/WriterWrapper.h
M Incremental dumps.vcxproj
M Objects/Revision.h
M XmlInput/XmlContributorProcessor.cpp
M XmlInput/XmlMediawikiProcessor.cpp
M XmlInput/XmlMediawikiProcessor.h
M XmlInput/XmlPageProcessor.cpp
M XmlInput/XmlPageProcessor.h
M XmlInput/XmlRevisionProcessor.cpp
M XmlInput/XmlSiteInfoProcessor.cpp
M XmlInput/XmlSiteInfoProcessor.h
M XmlWriter.cpp
M main.cpp
36 files changed, 568 insertions(+), 207 deletions(-)

Approvals:
  Petr Onderka: Verified; Looks good to me, approved



diff --git a/CMakeLists.txt b/CMakeLists.txt
index a3560ad..0218fe4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,6 +8,7 @@
 set(SOURCES_files_ClCompile
   Dump.cpp
   DumpException.cpp
+  DumpKind.cpp
   DumpObjects/DumpIpV4User.cpp
   DumpObjects/DumpIpV6User.cpp
   DumpObjects/DumpNamedUser.cpp
@@ -26,10 +27,11 @@
   Objects/Revision.cpp
   SevenZip.cpp
   SpaceManager.cpp
+  DumpWriters/ArticlesWriterWrapper.cpp
+  DumpWriters/CompositeWriter.cpp
+  DumpWriters/CurrentWriterWrapper.cpp
   DumpWriters/DumpWriter.cpp
-  DumpWriters/StubCurrentWriter.cpp
-  DumpWriters/StubHistoryWriter.cpp
-  DumpWriters/PagesHistoryWriter.cpp
+  DumpWriters/WriterWrapper.cpp
   Objects/User.cpp
   StringHelpers.cpp
   Objects/Timestamp.cpp
@@ -51,6 +53,7 @@
 set(SOURCES_files_ClInclude
   CollectionHelpers.h
   DumpException.h
+  DumpKind.h
   DumpObjects/DumpIpV4User.h
   DumpObjects/DumpIpV6User.h
   DumpObjects/DumpNamedUser.h
@@ -67,7 +70,6 @@
   Dump.h
   DumpObjects/DumpObject.h
   DumpObjects/DumpTraits.h
-  DumpWriters/DumpWriter.h
   DumpObjects/FileHeader.h
   Indexes/IndexInnerNode.h
   Indexes/IndexLeafNode.h
@@ -88,9 +90,12 @@
   Indexes/Iterators/IndexNodeIterator.h
   SevenZip.h
   SpaceManager.h
-  DumpWriters/StubCurrentWriter.h
-  DumpWriters/StubHistoryWriter.h
-  DumpWriters/PagesHistoryWriter.h
+  DumpWriters/ArticlesWriterWrapper.h
+  DumpWriters/CompositeWriter.h
+  DumpWriters/CurrentWriterWrapper.h
+  DumpWriters/DumpWriter.h
+  DumpWriters/IDumpWriter.h
+  DumpWriters/WriterWrapper.h
   Objects/User.h
   StringHelpers.h
   Objects/Timestamp.h
diff --git a/DumpKind.cpp b/DumpKind.cpp
new file mode 100644
index 0000000..0c82f26
--- /dev/null
+++ b/DumpKind.cpp
@@ -0,0 +1,37 @@
+#include "DumpKind.h"
+
+bool IsPages(DumpKind dumpKind)
+{
+    return ((std::uint8_t)dumpKind & (std::uint8_t)DumpKind::Pages) != 0;
+}
+
+bool IsStub(DumpKind dumpKind)
+{
+    return !IsPages(dumpKind);
+}
+
+bool IsCurrent(DumpKind dumpKind)
+{
+    return ((std::uint8_t)dumpKind & (std::uint8_t)DumpKind::Current) != 0;
+}
+
+bool IsHistory(DumpKind dumpKind)
+{
+    return !IsCurrent(dumpKind);
+}
+
+bool IsArticles(DumpKind dumpKind)
+{
+    return ((std::uint8_t)dumpKind & (std::uint8_t)DumpKind::Articles) != 0;
+}
+
+DumpKind operator |(DumpKind first, DumpKind second)
+{
+    return (DumpKind)((std::uint8_t)first | (std::uint8_t)second);
+}
+
+DumpKind operator |=(DumpKind &first, DumpKind second)
+{
+    first = first | second;
+    return first;
+}
\ No newline at end of file
diff --git a/DumpKind.h b/DumpKind.h
new file mode 100644
index 0000000..3b25f0d
--- /dev/null
+++ b/DumpKind.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <cstdint>
+
+enum class DumpKind : std::uint8_t
+{
+    None     = 0x00,
+    Pages    = 0x01,
+    Current  = 0x02,
+    Articles = 0x04
+};
+
+bool IsPages(DumpKind dumpKind);
+bool IsStub(DumpKind dumpKind);
+
+bool IsCurrent(DumpKind dumpKind);
+bool IsHistory(DumpKind dumpKind);
+
+bool IsArticles(DumpKind dumpKind);
+
+DumpKind operator |(DumpKind first, DumpKind second);
+DumpKind operator |=(DumpKind &first, DumpKind second);
\ No newline at end of file
diff --git a/DumpObjects/DumpRevision.cpp b/DumpObjects/DumpRevision.cpp
index 64f3b58..53dc06d 100644
--- a/DumpObjects/DumpRevision.cpp
+++ b/DumpObjects/DumpRevision.cpp
@@ -57,8 +57,16 @@
 
     if (!HasFlag(revision.Flags, RevisionFlags::TextDeleted))
     {
-        string compressedText = DumpTraits<string>::ReadLong(stream);
-        revision.Text = SevenZip::Decompress(compressedText);
+        if (IsPages(dump->fileHeader.Kind))
+        {
+            std::string compressedText = DumpTraits<string>::ReadLong(stream);
+            revision.Text = SevenZip::Decompress(compressedText);
+            revision.TextLength = revision.Text.length();
+        }
+        else
+        {
+            ReadValue(stream, revision.TextLength);
+        }
     }
 
     return revision;
@@ -94,7 +102,12 @@
         WriteValue(modelFormatId);
     
     if (!HasFlag(revision.Flags, RevisionFlags::TextDeleted))
-        DumpTraits<string>::WriteLong(*stream, withText ? compressedText : 
string());
+    {
+        if (withText)
+            DumpTraits<std::string>::WriteLong(*stream, compressedText);
+        else
+            WriteValue(revision.TextLength);
+    }
 }
 
 void DumpRevision::UpdateIndex(Offset offset, bool overwrite)
@@ -130,7 +143,12 @@
     if (modelFormatId != 0)
         result += ValueSize(modelFormatId);
     if (!HasFlag(revision.Flags, RevisionFlags::TextDeleted))
-        result += DumpTraits<string>::DumpSizeLong(withText ? compressedText : 
string());
+    {
+        if (withText)
+            result += DumpTraits<string>::DumpSizeLong(compressedText);
+        else
+            result += ValueSize(revision.TextLength);
+    }
 
     return result;
 }
diff --git a/DumpObjects/DumpTraits.h b/DumpObjects/DumpTraits.h
index 10f05eb..1f2cff2 100644
--- a/DumpObjects/DumpTraits.h
+++ b/DumpObjects/DumpTraits.h
@@ -112,7 +112,7 @@
         TargetTraits::Write(stream, target);
     }
 
-    static uint32_t DumpSize(const T value = 0)
+    static uint32_t DumpSize(const T value = T())
     {
         auto target = DumpConverter<T>::Convert(value);
         return TargetTraits::DumpSize(target);
@@ -178,7 +178,7 @@
         TargetTraits::Write(stream, target);
     }
 
-    static uint32_t DumpSize(const T value)
+    static uint32_t DumpSize(const T value = T())
     {
         auto target = static_cast<typename 
std::underlying_type<T>::type>(value);
         return TargetTraits::DumpSize(target);
diff --git a/DumpObjects/FileHeader.cpp b/DumpObjects/FileHeader.cpp
index d1c7009..82af112 100644
--- a/DumpObjects/FileHeader.cpp
+++ b/DumpObjects/FileHeader.cpp
@@ -4,9 +4,10 @@
 #include "../DumpException.h"
 
 FileHeader::FileHeader(
+    DumpKind kind,
     Offset fileEnd, Offset pageIdIndexRoot, Offset revisionIdIndexRoot, Offset 
modelFormatIndexRoot,
     Offset freeSpaceIndexRoot, Offset siteInfo, weak_ptr<WritableDump> dump)
-    : DumpObject(dump), FileEnd(fileEnd), PageIdIndexRoot(pageIdIndexRoot), 
RevisionIdIndexRoot(revisionIdIndexRoot),
+    : Kind(kind), DumpObject(dump), FileEnd(fileEnd), 
PageIdIndexRoot(pageIdIndexRoot), RevisionIdIndexRoot(revisionIdIndexRoot),
     ModelFormatIndexRoot(modelFormatIndexRoot), 
FreeSpaceIndexRoot(freeSpaceIndexRoot), SiteInfo(siteInfo)
 {}
 
@@ -15,6 +16,7 @@
     stream->write("WMID", 4);
     WriteValue(FileFormatVersion);
     WriteValue(FileDataVersion);
+    WriteValue(Kind);
 
     WriteValue(FileEnd);
     WriteValue(PageIdIndexRoot);
@@ -45,6 +47,8 @@
     if (strncmp(bytes, "WMID", 4) != 0 || bytes[4] != FileFormatVersion || 
bytes[5] != FileDataVersion)
         throw new DumpException();
 
+    DumpKind kind = DumpTraits<DumpKind>::Read(stream);
+
     Offset fileEnd = DumpTraits<Offset>::Read(stream);
     Offset pageIdIndexRoot = DumpTraits<Offset>::Read(stream);
     Offset revisionIdIndexRoot = DumpTraits<Offset>::Read(stream);
@@ -52,12 +56,12 @@
     Offset freeSpaceIndexRoot = DumpTraits<Offset>::Read(stream);
     Offset siteInfo = DumpTraits<Offset>::Read(stream);
 
-    return FileHeader(fileEnd, pageIdIndexRoot, revisionIdIndexRoot, 
modelFormatIndexRoot, freeSpaceIndexRoot, siteInfo, dump.GetSelf());
+    return FileHeader(kind, fileEnd, pageIdIndexRoot, revisionIdIndexRoot, 
modelFormatIndexRoot, freeSpaceIndexRoot, siteInfo, dump.GetSelf());
 }
 
 uint32_t FileHeader::Length()
 {
-    return 4 + 2 * DumpTraits<uint8_t>::DumpSize() + 6 * 
DumpTraits<Offset>::DumpSize();
+    return 4 + 2 * DumpTraits<std::uint8_t>::DumpSize() + 
DumpTraits<DumpKind>::DumpSize() + 6 * DumpTraits<Offset>::DumpSize();
 }
 
 uint32_t FileHeader::NewLength()
diff --git a/DumpObjects/FileHeader.h b/DumpObjects/FileHeader.h
index d1e8538..24f3ce7 100644
--- a/DumpObjects/FileHeader.h
+++ b/DumpObjects/FileHeader.h
@@ -3,6 +3,7 @@
 #include <iostream>
 #include "DumpObject.h"
 #include "Offset.h"
+#include "../DumpKind.h"
 
 class ReadableDump;
 
@@ -14,6 +15,7 @@
     static uint32_t Length();
 
     FileHeader(
+        DumpKind kind,
         Offset fileEnd, Offset pageIdIndexRoot, Offset revisionIdIndexRoot, 
Offset modelFormatIndexRoot,
         Offset freeSpaceIndexRoot, Offset siteInfo, weak_ptr<WritableDump> 
dump = weak_ptr<WritableDump>());
 protected:
@@ -27,6 +29,8 @@
     virtual void Write() override;
     virtual uint32_t NewLength() override;
 
+    DumpKind Kind;
+
     Offset FileEnd;
     Offset PageIdIndexRoot;
     Offset RevisionIdIndexRoot;
diff --git a/DumpWriters/ArticlesWriterWrapper.cpp 
b/DumpWriters/ArticlesWriterWrapper.cpp
new file mode 100644
index 0000000..229e910
--- /dev/null
+++ b/DumpWriters/ArticlesWriterWrapper.cpp
@@ -0,0 +1,48 @@
+#include "ArticlesWriterWrapper.h"
+#include "../DumpException.h"
+
+const std::int16_t UserNamespace = 2;
+
+void ArticlesWriterWrapper::StartPage(const std::shared_ptr<const Page> page)
+{
+    pageInlcuded = page->Namespace % 2 == 0 && page->Namespace != 
UserNamespace;
+
+    if (pageInlcuded)
+        wrapped->StartPage(page);
+}
+
+const std::vector<std::uint32_t> ArticlesWriterWrapper::GetRevisionIds() const
+{
+    if (!pageInlcuded)
+        throw DumpException();
+
+    return WriterWrapper::GetRevisionIds();
+}
+
+void ArticlesWriterWrapper::AddRevision(const std::shared_ptr<const Revision> 
revision)
+{
+    if (pageInlcuded)
+        wrapped->AddRevision(revision);
+}
+
+void ArticlesWriterWrapper::DeleteRevision(std::uint32_t revisionId)
+{
+    if (!pageInlcuded)
+        throw DumpException();
+
+    WriterWrapper::DeleteRevision(revisionId);
+}
+
+void ArticlesWriterWrapper::EndPage()
+{
+    if (pageInlcuded)
+    {
+        wrapped->EndPage();
+        pageInlcuded = false;
+    }
+}
+
+void ArticlesWriterWrapper::SetDumpKind(DumpKind dumpKind)
+{
+    wrapped->SetDumpKind(dumpKind | DumpKind::Articles);
+}
\ No newline at end of file
diff --git a/DumpWriters/ArticlesWriterWrapper.h 
b/DumpWriters/ArticlesWriterWrapper.h
new file mode 100644
index 0000000..f2f08b5
--- /dev/null
+++ b/DumpWriters/ArticlesWriterWrapper.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "WriterWrapper.h"
+
+class ArticlesWriterWrapper : public WriterWrapper
+{
+private:
+    bool pageInlcuded;
+public:
+    ArticlesWriterWrapper(std::unique_ptr<IDumpWriter> wrapped)
+        : WriterWrapper(std::move(wrapped)), pageInlcuded(false)
+    {}
+
+    virtual void StartPage(const std::shared_ptr<const Page> page) override;
+    virtual const std::vector<std::uint32_t> GetRevisionIds() const override;
+    virtual void AddRevision(const std::shared_ptr<const Revision> revision) 
override;
+    virtual void DeleteRevision(std::uint32_t revisionId) override;
+    virtual void EndPage() override;
+    virtual void SetDumpKind(DumpKind dumpKind) override;
+};
\ No newline at end of file
diff --git a/DumpWriters/CompositeWriter.cpp b/DumpWriters/CompositeWriter.cpp
new file mode 100644
index 0000000..5cd3d42
--- /dev/null
+++ b/DumpWriters/CompositeWriter.cpp
@@ -0,0 +1,49 @@
+#include "CompositeWriter.h"
+#include "../DumpException.h"
+
+void CompositeWriter::StartPage(const std::shared_ptr<const Page> page)
+{
+    for (auto &writer : writers)
+        writer->StartPage(page);
+}
+
+const std::vector<std::uint32_t> CompositeWriter::GetRevisionIds() const
+{
+    throw DumpException();
+}
+
+void CompositeWriter::AddRevision(const std::shared_ptr<const Revision> 
revision)
+{
+    for (auto &writer : writers)
+        writer->AddRevision(revision);
+}
+
+void CompositeWriter::DeleteRevision(std::uint32_t revisionId)
+{
+    for (auto &writer : writers)
+        writer->DeleteRevision(revisionId);
+}
+
+void CompositeWriter::EndPage()
+{
+    for (auto &writer : writers)
+        writer->EndPage();
+}
+
+void CompositeWriter::SetSiteInfo(const std::shared_ptr<const SiteInfo> 
siteInfo)
+{
+    for (auto &writer : writers)
+        writer->SetSiteInfo(siteInfo);
+}
+
+void CompositeWriter::SetDumpKind(DumpKind dumpKind)
+{
+    for (auto &writer : writers)
+        writer->SetDumpKind(dumpKind);
+}
+
+void CompositeWriter::WriteIndexes()
+{
+    for (auto &writer : writers)
+        writer->WriteIndexes();
+}
\ No newline at end of file
diff --git a/DumpWriters/CompositeWriter.h b/DumpWriters/CompositeWriter.h
new file mode 100644
index 0000000..cd6e647
--- /dev/null
+++ b/DumpWriters/CompositeWriter.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <memory>
+#include <vector>
+#include "IDumpWriter.h"
+
+class CompositeWriter : public IDumpWriter
+{
+private:
+    std::vector<std::unique_ptr<IDumpWriter>> writers;
+public:
+    CompositeWriter(std::vector<std::unique_ptr<IDumpWriter>> &writers)
+        : writers(std::move(writers))
+    {}
+
+    virtual void StartPage(const std::shared_ptr<const Page> page) override;
+    virtual const std::vector<std::uint32_t> GetRevisionIds() const override;
+    virtual void AddRevision(const std::shared_ptr<const Revision> revision) 
override;
+    virtual void DeleteRevision(std::uint32_t revisionId) override;
+    virtual void EndPage() override;
+    virtual void SetSiteInfo(const std::shared_ptr<const SiteInfo> siteInfo) 
override;
+    virtual void SetDumpKind(DumpKind dumpKind) override;
+    virtual void WriteIndexes() override;
+};
\ No newline at end of file
diff --git a/DumpWriters/CurrentWriterWrapper.cpp 
b/DumpWriters/CurrentWriterWrapper.cpp
new file mode 100644
index 0000000..03be130
--- /dev/null
+++ b/DumpWriters/CurrentWriterWrapper.cpp
@@ -0,0 +1,24 @@
+#include "CurrentWriterWrapper.h"
+
+void CurrentWriterWrapper::AddRevision(const std::shared_ptr<const Revision> 
revision)
+{
+    this->revision = revision;
+}
+
+void CurrentWriterWrapper::EndPage()
+{
+    for (uint32_t revisionId : wrapped->GetRevisionIds())
+    {
+        wrapped->DeleteRevision(revisionId);
+    }
+
+    wrapped->AddRevision(this->revision);
+    wrapped->EndPage();
+
+    revision = nullptr;
+}
+
+void CurrentWriterWrapper::SetDumpKind(DumpKind dumpKind)
+{
+    wrapped->SetDumpKind(dumpKind | DumpKind::Current);
+}
\ No newline at end of file
diff --git a/DumpWriters/CurrentWriterWrapper.h 
b/DumpWriters/CurrentWriterWrapper.h
new file mode 100644
index 0000000..b763d80
--- /dev/null
+++ b/DumpWriters/CurrentWriterWrapper.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "WriterWrapper.h"
+
+class CurrentWriterWrapper : public WriterWrapper
+{
+private:
+    std::shared_ptr<const Revision> revision;
+public:
+    CurrentWriterWrapper(std::unique_ptr<IDumpWriter> wrapped)
+        : WriterWrapper(std::move(wrapped))
+    {}
+
+    virtual void AddRevision(const std::shared_ptr<const Revision> revision) 
override;
+    virtual void EndPage() override;
+    virtual void SetDumpKind(DumpKind dumpKind) override;
+};
\ No newline at end of file
diff --git a/DumpWriters/DumpWriter.cpp b/DumpWriters/DumpWriter.cpp
index 8fbb0d8..3554f5f 100644
--- a/DumpWriters/DumpWriter.cpp
+++ b/DumpWriters/DumpWriter.cpp
@@ -1,4 +1,6 @@
 #include "DumpWriter.h"
+#include "../DumpObjects/DumpRevision.h"
+#include <algorithm>
 
 void DumpWriter::SetSiteInfo(const std::shared_ptr<const SiteInfo> siteInfo)
 {
@@ -10,4 +12,56 @@
 {
     this->page = unique_ptr<DumpPage>(new DumpPage(dump, page->PageId));
     this->page->page = *page;
-}
\ No newline at end of file
+}
+
+const std::vector<std::uint32_t> DumpWriter::GetRevisionIds() const
+{
+    return this->page->page.RevisionIds;
+}
+
+void DumpWriter::AddRevision(const shared_ptr<const Revision> revision)
+{
+    page->page.RevisionIds.push_back(revision->RevisionId);
+    revisions.push_back(revision);
+}
+
+void DumpWriter::DeleteRevision(std::uint32_t revisionId)
+{
+    dump->DeleteRevision(revisionId);
+
+    auto &revisionIds = page->page.RevisionIds;
+    auto toDeleteIt = std::find(revisionIds.begin(), revisionIds.end(), 
revisionId);
+    if (toDeleteIt == revisionIds.end())
+        throw DumpException();
+    
+    revisionIds.erase(toDeleteIt);
+}
+
+void DumpWriter::EndPage()
+{
+    page->Write();
+
+    for (auto revision : revisions)
+    {
+        DumpRevision dumpRevision(dump, withText);
+        dumpRevision.revision = *revision;
+        dumpRevision.Write();
+    }
+
+    page = nullptr;
+    revisions.clear();
+}
+
+void DumpWriter::SetDumpKind(DumpKind dumpKind)
+{
+    if (withText)
+        dumpKind |= DumpKind::Pages;
+
+    dump->fileHeader.Kind = dumpKind;
+    dump->fileHeader.Write();
+}
+
+void DumpWriter::WriteIndexes()
+{
+    dump->WriteIndexes();
+}
diff --git a/DumpWriters/DumpWriter.h b/DumpWriters/DumpWriter.h
index 4cc10d0..3efc08e 100644
--- a/DumpWriters/DumpWriter.h
+++ b/DumpWriters/DumpWriter.h
@@ -1,34 +1,30 @@
 #pragma once
 
-#include <memory>
-#include "../Objects/Page.h"
-#include "../Objects/Revision.h"
-#include "../Objects/SiteInfo.h"
+#include "IDumpWriter.h"
+#include "../DumpObjects/DumpPage.h"
 #include "../Dump.h"
 #include "../DumpObjects/DumpPage.h"
 
-class DumpWriterBase
-{
-public:
-    virtual void StartPage(const std::shared_ptr<const Page> page) = 0;
-    virtual void AddRevision(const std::shared_ptr<const Revision> revision) = 
0;
-    virtual void EndPage() = 0;
-    virtual void SetSiteInfo(const std::shared_ptr<const SiteInfo> siteInfo) = 
0;
-};
 
-class DumpWriter : public DumpWriterBase
+class DumpWriter : public IDumpWriter
 {
-protected:
+private:
     std::shared_ptr<WritableDump> dump;
     unique_ptr<DumpPage> page;
+    vector<shared_ptr<const Revision>> revisions;
+    bool withText;
 
 public:
-    DumpWriter(std::shared_ptr<WritableDump> dump)
-        : dump(dump)
+    DumpWriter(std::shared_ptr<WritableDump> dump, bool withText)
+        : dump(dump), withText(withText)
     {}
 
     virtual void StartPage(const std::shared_ptr<const Page> page) override;
-    virtual void AddRevision(const std::shared_ptr<const Revision> revision) 
override = 0;
-    virtual void EndPage() override = 0;
+    virtual const std::vector<std::uint32_t> GetRevisionIds() const override;
+    virtual void AddRevision(const std::shared_ptr<const Revision> revision) 
override;
+    virtual void DeleteRevision(std::uint32_t revisionId) override;
+    virtual void EndPage() override;
     virtual void SetSiteInfo(const std::shared_ptr<const SiteInfo> siteInfo) 
override;
+    virtual void SetDumpKind(DumpKind dumpKind) override;
+    virtual void WriteIndexes() override;
 };
\ No newline at end of file
diff --git a/DumpWriters/IDumpWriter.h b/DumpWriters/IDumpWriter.h
new file mode 100644
index 0000000..fa75de0
--- /dev/null
+++ b/DumpWriters/IDumpWriter.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <memory>
+#include "../Objects/Page.h"
+#include "../Objects/Revision.h"
+#include "../Objects/SiteInfo.h"
+#include "../DumpKind.h"
+
+class IDumpWriter
+{
+public:
+    virtual void StartPage(const std::shared_ptr<const Page> page) = 0;
+    virtual const std::vector<std::uint32_t> GetRevisionIds() const = 0;
+    virtual void AddRevision(const std::shared_ptr<const Revision> revision) = 
0;
+    virtual void DeleteRevision(std::uint32_t revisionId) = 0;
+    virtual void EndPage() = 0;
+    virtual void SetSiteInfo(const std::shared_ptr<const SiteInfo> siteInfo) = 
0;
+    virtual void SetDumpKind(DumpKind dumpKind) = 0;
+    virtual void WriteIndexes() = 0;
+
+    virtual ~IDumpWriter() {}
+};
diff --git a/DumpWriters/PagesHistoryWriter.cpp 
b/DumpWriters/PagesHistoryWriter.cpp
deleted file mode 100644
index 65e912f..0000000
--- a/DumpWriters/PagesHistoryWriter.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "PagesHistoryWriter.h"
-#include "../DumpObjects/DumpRevision.h"
-
-PagesHistoryWriter::PagesHistoryWriter(shared_ptr<WritableDump> dump)
-    : DumpWriter(dump)
-{}
-
-void PagesHistoryWriter::AddRevision(const shared_ptr<const Revision> revision)
-{
-    page->page.RevisionIds.push_back(revision->RevisionId);
-    revisions.push_back(revision);
-}
-
-void PagesHistoryWriter::EndPage()
-{
-    page->Write();
-
-    for (auto revision : revisions)
-    {
-        DumpRevision dumpRevision(dump, true);
-        dumpRevision.revision = *revision;
-        dumpRevision.Write();
-    }
-
-    page = nullptr;
-    revisions.clear();
-}
\ No newline at end of file
diff --git a/DumpWriters/PagesHistoryWriter.h b/DumpWriters/PagesHistoryWriter.h
deleted file mode 100644
index 9c48d0f..0000000
--- a/DumpWriters/PagesHistoryWriter.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "DumpWriter.h"
-#include "../DumpObjects/DumpPage.h"
-
-class PagesHistoryWriter : public DumpWriter
-{
-private:
-    vector<shared_ptr<const Revision>> revisions;
-public:
-    PagesHistoryWriter(shared_ptr<WritableDump> dump);
-
-    virtual void AddRevision(const shared_ptr<const Revision> revision) 
override;
-    virtual void EndPage() override;
-};
\ No newline at end of file
diff --git a/DumpWriters/StubCurrentWriter.cpp 
b/DumpWriters/StubCurrentWriter.cpp
deleted file mode 100644
index 6c520f7..0000000
--- a/DumpWriters/StubCurrentWriter.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "StubCurrentWriter.h"
-#include "../DumpObjects/DumpRevision.h"
-
-StubCurrentWriter::StubCurrentWriter(shared_ptr<WritableDump> dump)
-    : DumpWriter(dump)
-{}
-
-void StubCurrentWriter::AddRevision(const shared_ptr<const Revision> revision)
-{
-    this->revision = revision;
-}
-
-void StubCurrentWriter::EndPage()
-{
-    for (uint32_t revisionId : page->page.RevisionIds)
-    {
-        dump->DeleteRevision(revisionId);
-    }
-
-    page->page.RevisionIds.clear();
-    page->page.RevisionIds.push_back(revision->RevisionId);
-
-    page->Write();
-
-    DumpRevision dumpRevision(dump, false);
-    dumpRevision.revision = *revision;
-    dumpRevision.Write();
-
-    page = nullptr;
-    revision = nullptr;
-}
\ No newline at end of file
diff --git a/DumpWriters/StubCurrentWriter.h b/DumpWriters/StubCurrentWriter.h
deleted file mode 100644
index ab3210d..0000000
--- a/DumpWriters/StubCurrentWriter.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "DumpWriter.h"
-#include "../DumpObjects/DumpPage.h"
-
-class StubCurrentWriter : public DumpWriter
-{
-private:
-    shared_ptr<const Revision> revision;
-public:
-    StubCurrentWriter(shared_ptr<WritableDump> dump);
-
-    virtual void AddRevision(const shared_ptr<const Revision> revision) 
override;
-    virtual void EndPage() override;
-};
\ No newline at end of file
diff --git a/DumpWriters/StubHistoryWriter.cpp 
b/DumpWriters/StubHistoryWriter.cpp
deleted file mode 100644
index e4aa4ed..0000000
--- a/DumpWriters/StubHistoryWriter.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "StubHistoryWriter.h"
-#include "../DumpObjects/DumpRevision.h"
-
-StubHistoryWriter::StubHistoryWriter(shared_ptr<WritableDump> dump)
-    : DumpWriter(dump)
-{}
-
-void StubHistoryWriter::AddRevision(const shared_ptr<const Revision> revision)
-{
-    page->page.RevisionIds.push_back(revision->RevisionId);
-    revisions.push_back(revision);
-}
-
-void StubHistoryWriter::EndPage()
-{
-    page->Write();
-
-    for (auto revision : revisions)
-    {
-        DumpRevision dumpRevision(dump, false);
-        dumpRevision.revision = *revision;
-        dumpRevision.Write();
-    }
-
-    page = nullptr;
-    revisions.clear();
-}
\ No newline at end of file
diff --git a/DumpWriters/StubHistoryWriter.h b/DumpWriters/StubHistoryWriter.h
deleted file mode 100644
index ac9b6cf..0000000
--- a/DumpWriters/StubHistoryWriter.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "DumpWriter.h"
-#include "../DumpObjects/DumpPage.h"
-
-class StubHistoryWriter : public DumpWriter
-{
-private:
-    vector<shared_ptr<const Revision>> revisions;
-public:
-    StubHistoryWriter(shared_ptr<WritableDump> dump);
-
-    virtual void AddRevision(const shared_ptr<const Revision> revision) 
override;
-    virtual void EndPage() override;
-};
\ No newline at end of file
diff --git a/DumpWriters/WriterWrapper.cpp b/DumpWriters/WriterWrapper.cpp
new file mode 100644
index 0000000..7f30504
--- /dev/null
+++ b/DumpWriters/WriterWrapper.cpp
@@ -0,0 +1,36 @@
+#include "WriterWrapper.h"
+
+void WriterWrapper::StartPage(const std::shared_ptr<const Page> page)
+{
+    wrapped->StartPage(page);
+}
+
+const std::vector<std::uint32_t> WriterWrapper::GetRevisionIds() const
+{
+    return wrapped->GetRevisionIds();
+}
+
+void WriterWrapper::AddRevision(const std::shared_ptr<const Revision> revision)
+{
+    wrapped->AddRevision(revision);
+}
+
+void WriterWrapper::DeleteRevision(std::uint32_t revisionId)
+{
+    wrapped->DeleteRevision(revisionId);
+}
+
+void WriterWrapper::EndPage()
+{
+    wrapped->EndPage();
+}
+
+void WriterWrapper::SetSiteInfo(const std::shared_ptr<const SiteInfo> siteInfo)
+{
+    wrapped->SetSiteInfo(siteInfo);
+}
+
+void WriterWrapper::WriteIndexes()
+{
+    wrapped->WriteIndexes();
+}
\ No newline at end of file
diff --git a/DumpWriters/WriterWrapper.h b/DumpWriters/WriterWrapper.h
new file mode 100644
index 0000000..6a88e42
--- /dev/null
+++ b/DumpWriters/WriterWrapper.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "IDumpWriter.h"
+
+class WriterWrapper : public IDumpWriter
+{
+protected:
+    std::unique_ptr<IDumpWriter> wrapped;
+public:
+    WriterWrapper(std::unique_ptr<IDumpWriter> wrapped)
+        : wrapped(std::move(wrapped))
+    {}
+
+    virtual void StartPage(const std::shared_ptr<const Page> page) override;
+    virtual const std::vector<std::uint32_t> GetRevisionIds() const override;
+    virtual void AddRevision(const std::shared_ptr<const Revision> revision) 
override;
+    virtual void DeleteRevision(std::uint32_t revisionId) override;
+    virtual void EndPage() override;
+    virtual void SetSiteInfo(const std::shared_ptr<const SiteInfo> siteInfo) 
override;
+    virtual void SetDumpKind(DumpKind dumpKind) override = 0;
+    virtual void WriteIndexes() override;
+};
\ No newline at end of file
diff --git a/Incremental dumps.vcxproj b/Incremental dumps.vcxproj
index 6711c65..2a55391 100644
--- a/Incremental dumps.vcxproj
+++ b/Incremental dumps.vcxproj
@@ -82,6 +82,7 @@
   <ItemGroup>
     <ClCompile Include="Dump.cpp" />
     <ClCompile Include="DumpException.cpp" />
+    <ClCompile Include="DumpKind.cpp" />
     <ClCompile Include="DumpObjects\DumpIpV4User.cpp" />
     <ClCompile Include="DumpObjects\DumpIpV6User.cpp" />
     <ClCompile Include="DumpObjects\DumpNamedUser.cpp" />
@@ -90,6 +91,7 @@
     <ClCompile Include="DumpObjects\FileHeader.cpp" />
     <ClInclude Include="CollectionHelpers.h" />
     <ClInclude Include="DumpException.h" />
+    <ClInclude Include="DumpKind.h" />
     <ClInclude Include="DumpObjects\DumpIpV4User.h" />
     <ClInclude Include="DumpObjects\DumpIpV6User.h" />
     <ClInclude Include="DumpObjects\DumpNamedUser.h" />
@@ -98,8 +100,10 @@
     <ClInclude Include="DumpObjects\DumpRevision.h" />
     <ClInclude Include="DumpObjects\DumpSiteInfo.h" />
     <ClInclude Include="DumpObjects\DumpUser.h" />
-    <ClInclude Include="DumpWriters\PagesHistoryWriter.h" />
-    <ClInclude Include="DumpWriters\StubHistoryWriter.h" />
+    <ClInclude Include="DumpWriters\ArticlesWriterWrapper.h" />
+    <ClInclude Include="DumpWriters\CompositeWriter.h" />
+    <ClInclude Include="DumpWriters\DumpWriter.h" />
+    <ClInclude Include="DumpWriters\WriterWrapper.h" />
     <ClInclude Include="Indexes\Index.h" />
     <ClInclude Include="Indexes\IndexInnerNode.h" />
     <ClInclude Include="Indexes\IndexLeafNode.tpp">
@@ -113,9 +117,10 @@
     <ClCompile Include="DumpObjects\DumpPage.cpp" />
     <ClCompile Include="DumpObjects\DumpRevision.cpp" />
     <ClCompile Include="DumpObjects\DumpUser.cpp" />
+    <ClCompile Include="DumpWriters\ArticlesWriterWrapper.cpp" />
+    <ClCompile Include="DumpWriters\CompositeWriter.cpp" />
     <ClCompile Include="DumpWriters\DumpWriter.cpp" />
-    <ClCompile Include="DumpWriters\PagesHistoryWriter.cpp" />
-    <ClCompile Include="DumpWriters\StubHistoryWriter.cpp" />
+    <ClCompile Include="DumpWriters\WriterWrapper.cpp" />
     <ClCompile Include="Objects\IpV4User.cpp" />
     <ClCompile Include="main.cpp" />
     <ClCompile Include="DumpObjects\Offset.cpp" />
@@ -125,7 +130,7 @@
     <ClCompile Include="Objects\Revision.cpp" />
     <ClCompile Include="SevenZip.cpp" />
     <ClCompile Include="SpaceManager.cpp" />
-    <ClCompile Include="DumpWriters\StubCurrentWriter.cpp" />
+    <ClCompile Include="DumpWriters\CurrentWriterWrapper.cpp" />
     <ClCompile Include="Objects\User.cpp" />
     <ClCompile Include="StringHelpers.cpp" />
     <ClCompile Include="Objects\Timestamp.cpp" />
@@ -147,7 +152,7 @@
     <ClInclude Include="Dump.h" />
     <ClInclude Include="DumpObjects\DumpObject.h" />
     <ClInclude Include="DumpObjects\DumpTraits.h" />
-    <ClInclude Include="DumpWriters\DumpWriter.h" />
+    <ClInclude Include="DumpWriters\IDumpWriter.h" />
     <ClInclude Include="DumpObjects\FileHeader.h" />
     <ClInclude Include="Indexes\IndexLeafNode.h" />
     <ClInclude Include="Indexes\IndexNode.h" />
@@ -166,7 +171,7 @@
     <ClInclude Include="Objects\SiteInfo.h" />
     <ClInclude Include="SevenZip.h" />
     <ClInclude Include="SpaceManager.h" />
-    <ClInclude Include="DumpWriters\StubCurrentWriter.h" />
+    <ClInclude Include="DumpWriters\CurrentWriterWrapper.h" />
     <ClInclude Include="Objects\User.h" />
     <ClInclude Include="StringHelpers.h" />
     <ClInclude Include="Objects\Timestamp.h" />
diff --git a/Objects/Revision.h b/Objects/Revision.h
index 79ab73f..a31ce57 100644
--- a/Objects/Revision.h
+++ b/Objects/Revision.h
@@ -5,10 +5,7 @@
 #include "User.h"
 #include "Timestamp.h"
 
-using std::shared_ptr;
-using std::string;
-
-enum class RevisionFlags : uint8_t
+enum class RevisionFlags : std::uint8_t
 {
     None      = 0x00,
 
@@ -34,13 +31,14 @@
     Revision();
 
     RevisionFlags Flags;
-    uint32_t RevisionId;
-    uint32_t ParentId;
+    std::uint32_t RevisionId;
+    std::uint32_t ParentId;
     Timestamp DateTime;
-    shared_ptr<User> Contributor;
-    string Comment;
-    string Text;
-    string Sha1;
-    string Model;
-    string Format;
+    std::shared_ptr<User> Contributor;
+    std::string Comment;
+    std::string Text;
+    std::uint32_t TextLength;
+    std::string Sha1;
+    std::string Model;
+    std::string Format;
 };
\ No newline at end of file
diff --git a/XmlInput/XmlContributorProcessor.cpp 
b/XmlInput/XmlContributorProcessor.cpp
index 3c4c175..be24008 100644
--- a/XmlInput/XmlContributorProcessor.cpp
+++ b/XmlInput/XmlContributorProcessor.cpp
@@ -34,6 +34,6 @@
     else
         user = std::make_shared<NamedUser>(processor.id, processor.userName);
 
-    revision->Contributor = shared_ptr<User>(user);
+    revision->Contributor = std::shared_ptr<User>(user);
     revision->Flags |= user->UserKind();
 }
\ No newline at end of file
diff --git a/XmlInput/XmlMediawikiProcessor.cpp 
b/XmlInput/XmlMediawikiProcessor.cpp
index 948b76c..961fb2e 100644
--- a/XmlInput/XmlMediawikiProcessor.cpp
+++ b/XmlInput/XmlMediawikiProcessor.cpp
@@ -5,7 +5,7 @@
 
 void mediawikiHandler(XML::Element &elem, void *userData)
 {
-    auto writer = (DumpWriter*)userData;
+    auto writer = (IDumpWriter*)userData;
 
     std::string lang = elem.GetAttribute("xml:lang");
 
@@ -21,7 +21,7 @@
     elem.Process(handlers, writer);
 }
 
-void XmlMediawikiProcessor::Process(DumpWriter *writer, std::string 
inputFileName)
+void XmlMediawikiProcessor::Process(IDumpWriter *writer, std::string 
inputFileName)
 {
     XML::FileInputStream stream = XML::FileInputStream(inputFileName.c_str());
 
diff --git a/XmlInput/XmlMediawikiProcessor.h b/XmlInput/XmlMediawikiProcessor.h
index 350ec8d..23cc1eb 100644
--- a/XmlInput/XmlMediawikiProcessor.h
+++ b/XmlInput/XmlMediawikiProcessor.h
@@ -9,5 +9,5 @@
     XmlMediawikiProcessor()
     {}
 public:
-    static void Process(DumpWriter *writer, std::string inputFileName);
+    static void Process(IDumpWriter *writer, std::string inputFileName);
 };
\ No newline at end of file
diff --git a/XmlInput/XmlPageProcessor.cpp b/XmlInput/XmlPageProcessor.cpp
index eaaab7f..75c1907 100644
--- a/XmlInput/XmlPageProcessor.cpp
+++ b/XmlInput/XmlPageProcessor.cpp
@@ -19,7 +19,7 @@
     dumpWriter->EndPage();
 }
 
-XmlPageProcessor::XmlPageProcessor(const shared_ptr<Page> page, DumpWriter* 
dumpWriter)
+XmlPageProcessor::XmlPageProcessor(const shared_ptr<Page> page, IDumpWriter* 
dumpWriter)
     : page(page), dumpWriter(dumpWriter), pageWritten(false)
 {}
 
@@ -34,7 +34,7 @@
         XML::Handler::END
     };
 
-    XmlPageProcessor pageProcessor(make_shared<Page>(), (DumpWriter*)userData);
+    XmlPageProcessor pageProcessor(make_shared<Page>(), 
(IDumpWriter*)userData);
 
     elem.Process(handlers, &pageProcessor);
 
diff --git a/XmlInput/XmlPageProcessor.h b/XmlInput/XmlPageProcessor.h
index d3c6bde..7fbdd51 100644
--- a/XmlInput/XmlPageProcessor.h
+++ b/XmlInput/XmlPageProcessor.h
@@ -10,10 +10,10 @@
 class XmlPageProcessor
 {
 private:
-    DumpWriter* dumpWriter;
+    IDumpWriter* dumpWriter;
     bool pageWritten;
 
-    XmlPageProcessor(const shared_ptr<Page> page, DumpWriter* dumpWriter);
+    XmlPageProcessor(const shared_ptr<Page> page, IDumpWriter* dumpWriter);
 
     void writePage();
     void completePage();
diff --git a/XmlInput/XmlRevisionProcessor.cpp 
b/XmlInput/XmlRevisionProcessor.cpp
index ae42a72..5e7c86e 100644
--- a/XmlInput/XmlRevisionProcessor.cpp
+++ b/XmlInput/XmlRevisionProcessor.cpp
@@ -33,7 +33,10 @@
                 if (elem.GetAttribute("deleted") != nullptr)
                     revision->Flags |= RevisionFlags::TextDeleted;
                 else
+                {
                     revision->Text = readElementData(elem);
+                    revision->TextLength = revision->Text.length();
+                }
             }),
         XML::Handler("sha1", [](XML::Element &elem, void *userData) { 
((Revision*)userData)->Sha1 = readElementData(elem); }),
         XML::Handler("model", [](XML::Element &elem, void *userData) { 
((Revision*)userData)->Model = readElementData(elem); }),
diff --git a/XmlInput/XmlSiteInfoProcessor.cpp 
b/XmlInput/XmlSiteInfoProcessor.cpp
index 8978d8b..391304f 100644
--- a/XmlInput/XmlSiteInfoProcessor.cpp
+++ b/XmlInput/XmlSiteInfoProcessor.cpp
@@ -3,7 +3,7 @@
 #include "../XmlUtils.h"
 #include <tuple>
 
-XmlSiteInfoProcessor::XmlSiteInfoProcessor(DumpWriter* writer)
+XmlSiteInfoProcessor::XmlSiteInfoProcessor(IDumpWriter* writer)
     : siteInfo(std::make_shared<SiteInfo>()), writer(writer)
 {}
 
diff --git a/XmlInput/XmlSiteInfoProcessor.h b/XmlInput/XmlSiteInfoProcessor.h
index 9176048..391eb0d 100644
--- a/XmlInput/XmlSiteInfoProcessor.h
+++ b/XmlInput/XmlSiteInfoProcessor.h
@@ -8,11 +8,11 @@
 class XmlSiteInfoProcessor
 {
 private:
-    DumpWriter *writer;
+    IDumpWriter *writer;
 public:
     shared_ptr<SiteInfo> siteInfo;
 
-    XmlSiteInfoProcessor(DumpWriter *writer);
+    XmlSiteInfoProcessor(IDumpWriter *writer);
 
     static Case ParseCase(const std::string &caseString);
     static void Handler(XML::Element &elem, void *userData);
diff --git a/XmlWriter.cpp b/XmlWriter.cpp
index 2b96cac..3c823dc 100644
--- a/XmlWriter.cpp
+++ b/XmlWriter.cpp
@@ -137,6 +137,8 @@
 
             if (HasFlag(revision.Flags, RevisionFlags::TextDeleted))
                 output.WriteAttr("deleted", "deleted");
+            else if (IsStub(dump->fileHeader.Kind))
+                output.WriteAttr("bytes", (int)revision.TextLength);
             else
                 output.WriteAttr("xml:space", "preserve");
 
diff --git a/main.cpp b/main.cpp
index efde1a1..3d4e8c3 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,5 +1,9 @@
 #include <iostream>
-#include "DumpWriters/PagesHistoryWriter.h"
+#include <queue>
+#include "DumpWriters/CompositeWriter.h"
+#include "DumpWriters/DumpWriter.h"
+#include "DumpWriters/CurrentWriterWrapper.h"
+#include "DumpWriters/ArticlesWriterWrapper.h"
 #include "XmlInput/XmlMediawikiProcessor.h"
 #include "XmlWriter.h"
 #include "Dump.h"
@@ -7,19 +11,95 @@
 void printUsage()
 {
     std::cout << "Usage:\n";
-    std::cout << "creating dump: idumps c[reate] source.xml dump.id\n";
+    std::cout << "creating dump: idumps c[reate] source.xml spec dump.id\n";
+    std::cout << " spec is a 2 or 3-letter string that describes what kind of 
dump to create:\n";
+    std::cout << " 1. letter: p for pages dump or s for stub dump:\n";
+    std::cout << " 2. letter: h for history dump or c for current dump:\n";
+    std::cout << " 3. optional letter: a for articles dump:\n";
+    std::cout << " example: sh for stub-meta-history, pca for 
pages-articles\n";
     std::cout << "reading dump: idumps r[ead] dump.id output.xml\n";
 }
 
-void createDump(string inputFileName, string outputFileName)
+std::unique_ptr<IDumpWriter> createWriter(std::queue<std::string> &parameters)
 {
-    auto dump = WritableDump::Create(outputFileName);
+    std::unique_ptr<IDumpWriter> nullResult;
 
-    PagesHistoryWriter writer(dump);
+    if (parameters.size() < 2)
+        return nullResult;
+
+    auto spec = parameters.front();
+    parameters.pop();
+
+    if (spec.length() < 2 || spec.length() > 3)
+        return nullResult;
+
+    auto fileName = parameters.front();
+    parameters.pop();
+
+    bool withText;
+    if (spec[0] == 'p')
+        withText = true;
+    else if (spec[0] == 's')
+        withText = false;
+    else
+        return nullResult;
+
+    bool current;
+    if (spec[1] == 'c')
+        current = true;
+    else if (spec[1] == 'h')
+        current = false;
+    else
+        return nullResult;
+
+    bool articles = false;
+    if (spec.length() == 3)
+    {
+        if (spec[2] == 'a')
+            articles = true;
+        else
+            return nullResult;
+    }
+
+    auto dump = WritableDump::Create(fileName);
+
+    auto writer = std::unique_ptr<IDumpWriter>(new DumpWriter(dump, withText));
+
+    if (current)
+        writer = std::unique_ptr<IDumpWriter>(new 
CurrentWriterWrapper(std::move(writer)));
+
+    if (articles)
+        writer = std::unique_ptr<IDumpWriter>(new 
ArticlesWriterWrapper(std::move(writer)));
+
+    return writer;
+}
+
+bool createDump(std::queue<std::string> &parameters)
+{
+    std::string inputFileName = parameters.front();
+    parameters.pop();
+
+    std::vector<std::unique_ptr<IDumpWriter>> writers;
+
+    while (!parameters.empty())
+    {
+        auto writer = createWriter(parameters);
+
+        if (writer == nullptr)
+            return false;
+
+        writers.push_back(std::move(writer));
+    }
+
+    CompositeWriter writer(writers);
+
+    writer.SetDumpKind(DumpKind::None);
 
     XmlMediawikiProcessor::Process(&writer, inputFileName);
 
-    dump->WriteIndexes();
+    writer.WriteIndexes();
+
+    return true;
 }
 
 void readDump(string dumpFileName, string outputFileName)
@@ -41,14 +121,15 @@
 
     if (action == "c" || action == "create")
     {
-        if (argc != 4)
+        std::queue<std::string> parameters;
+
+        for (int i = 2; i < argc; i++)
+            parameters.push(argv[i]);
+
+        if (!createDump(parameters))
         {
-            std::cout << "Invalid number of parameters\n";
+            std::cout << "Invalid parameters\n";
             printUsage();
-        }
-        else
-        {
-            createDump(argv[2], argv[3]);
         }
     }
     else if (action == "r" || action == "read")

-- 
To view, visit https://gerrit.wikimedia.org/r/76736
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ibdd75afc5133790cef878ffe5a5ea41c83b0da98
Gerrit-PatchSet: 3
Gerrit-Project: operations/dumps/incremental
Gerrit-Branch: gsoc
Gerrit-Owner: Petr Onderka <[email protected]>
Gerrit-Reviewer: Petr Onderka <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to