Joedb 9.1.4
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
joedb_merge.cpp
Go to the documentation of this file.
2#include "joedb/Multiplexer.h"
7#include "joedb/ui/dump.h"
8#include "joedb/ui/merge.h"
10
11#include <iostream>
12#include <memory>
13#include <iomanip>
14
15namespace joedb
16{
17 /////////////////////////////////////////////////////////////////////////////
18 static int merge_main(int argc, char **argv)
19 /////////////////////////////////////////////////////////////////////////////
20 {
21 if (argc < 2)
22 {
23 std::cerr << "usage: " << argv[0];
24 std::cerr << " <db_1.joedb> ... <db_N.joedb> <output.joedb>\n";
25 std::cerr << "or read file names from input stream: " << argv[0];
26 std::cerr << " <output.joedb> <file_list.txt\n";
27 std::cerr << "Note: output file must not already exist\n";
28 return 1;
29 }
30
31 //
32 // Create output file
33 //
34 File output_file(argv[argc - 1], Open_Mode::create_new);
35 Writable_Journal output_journal(output_file);
36
37 //
38 // List of files to be merged
39 //
40 std::vector<std::string> file_names;
41
42 for (int i = 1; i < argc - 1; i++)
43 file_names.emplace_back(argv[i]);
44
45 if (file_names.empty())
46 {
47 std::cerr << "No input file on the command line: reading file names from standard input.\n";
48
49 std::string file_name;
50 while (std::cin >> file_name) // note: no file name with white space
51 file_names.emplace_back(std::move(file_name));
52 }
53
54 if (file_names.empty())
55 {
56 std::cerr << "Error: no input file\n";
57 return 1;
58 }
59
60 //
61 // Build merged db by looping over all files
62 //
63 std::string reference_schema;
64 std::unique_ptr<Database> merged_db;
65 const int width = int(std::to_string(file_names.size()).size());
66 int errors = 0;
67
68 for (size_t i = 0; i < file_names.size(); i++)
69 {
70 std::cerr << std::setw(width) << i + 1 << " / ";
71 std::cerr << file_names.size() << ": " << file_names[i] << "...";
72
73 try
74 {
75 std::unique_ptr<Database> db(new Database());
76
77 File input_file(file_names[i], Open_Mode::read_existing);
78 Readonly_Journal input_journal(input_file);
79
80 Memory_File schema_file;
81 Writable_Journal schema_journal(schema_file);
82
83 {
84 Selective_Writable schema_filter
85 (
86 schema_journal,
88 );
89
90 std::unique_ptr<Selective_Writable> output_schema;
91 std::unique_ptr<Multiplexer> multiplexer;
92
93 if (merged_db)
94 {
95 multiplexer.reset(new Multiplexer{*db, schema_filter});
96 }
97 else
98 {
99 output_schema.reset
100 (
101 new Selective_Writable
102 (
103 output_journal,
105 )
106 );
107
108 multiplexer.reset(new Multiplexer{*db, schema_filter, *output_schema});
109 }
110
111 input_journal.replay_log(*multiplexer);
112 }
113
114 //
115 // Check that all databases have the same schema
116 //
117 schema_journal.default_checkpoint();
118 if (!merged_db)
119 reference_schema = schema_file.get_data();
120 else if (schema_file.get_data() != reference_schema)
121 throw Exception
122 (
123 file_names[i] +
124 std::string(" does not have the same schema as ") +
125 file_names[0]
126 );
127
128 //
129 // Merge into the in-memory database
130 //
131 if (!merged_db)
132 merged_db = std::move(db);
133 else
134 merge(*merged_db, *db);
135 }
136 catch (const Exception &e)
137 {
138 std::cerr << ' ' << e.what();
139 errors++;
140 }
141
142 std::cerr << '\n';
143 }
144
145 if (merged_db)
146 {
147 dump_data(*merged_db, output_journal);
148
149 if (errors > 0)
150 std::cerr << "Number of errors: " << errors << '\n';
151
152 return 0;
153 }
154 else
155 return 1;
156 }
157}
158
159/////////////////////////////////////////////////////////////////////////////
160int main(int argc, char **argv)
161/////////////////////////////////////////////////////////////////////////////
162{
163 return joedb::main_exception_catcher(joedb::merge_main, argc, argv);
164}
int main()
@ create_new
fails if already exists, locks the file for writing
@ read_existing
fails if does not exist
int main_exception_catcher(int(*main)(int, char **), int argc, char **argv)
Catch exception from main.
void merge(Database &merged, const Database &db)
Definition merge.cpp:5
void dump_data(const Readable &db, Writable &writable)
Definition dump.cpp:119
Definition Blob.h:7
JOEDB_FILE File
Definition File.h:25