Skip to content

Commit e2c19ad

Browse files
Added TableOStream container
1 parent 6e8521f commit e2c19ad

File tree

2 files changed

+196
-74
lines changed

2 files changed

+196
-74
lines changed

sqlite3pp_ez.cpp

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ namespace sqlite3pp
293293
return sql_base::global_db.extended_error_code();
294294
}
295295

296+
////////////////////////////////////////////////////////////////////////////////////////////
296297
// sqlite_master is used when querying all the tables in a SQLite DB
297298
class sqlite_master
298299
{
@@ -309,7 +310,20 @@ namespace sqlite3pp
309310
StrType tbl_name;
310311
StrType rootpage;
311312
StrType sql;
313+
template<class T> T& OStream(T& t) const
314+
{
315+
//t.os << t.str(Ext) << t.d << t.str(PrgLangName) << t.d << t.str(ProfileName) << t.d << t.str(ExecType);
316+
return t;
317+
}
318+
friend std::ostream& operator<<(std::ostream& os, const sqlite_master& t);
319+
friend std::wostream& operator<<(std::wostream& os, const sqlite_master& t);
320+
static StrType Delimiter() { return ","; }
321+
312322
};
323+
// Part of sqlite3pp::TableOStream interface. Required if using TableOStream container or operator<<(). To exclude TableOStream interface, set exclude_ostream_operator to true when creating this class through SQLiteClassBuilder.
324+
std::ostream& operator<<(std::ostream& os, const sqlite_master& t) { sqlite3pp::ostream_a o(os, t.Delimiter()); return t.OStream(o).os; }
325+
std::wostream& operator<<(std::wostream& os, const sqlite_master& t) { sqlite3pp::ostream_w o(os, t.Delimiter()); return t.OStream(o).os; }
326+
313327

314328
// Predefined string options
315329
const StrOptions SQLiteClassBuilder::strOpt_std_string = { "std::string", "", "", "#include <string>" };
@@ -321,10 +335,10 @@ namespace sqlite3pp
321335
const MiscOptions SQLiteClassBuilder::MiscOpt_min = { ",", true, true, true, true, true, false, false, true, true };
322336
const MiscOptions SQLiteClassBuilder::MiscOpt_var = { ",", true, true, true, true, true, true, false, true, true };
323337
// Default settings for HeaderOpt
324-
const HeaderOpt SQLiteClassBuilder::HeaderDefaultOpt = { "SQL\\", "sql_", "" };
338+
const HeaderOpt SQLiteClassBuilder::HeaderDefaultOpt = { "SQL\\", "sql_", "", "h", "sqlite3pp_ez.h" };
325339

326340
const char *SQLiteClassBuilder::Nill = "#NILL#";
327-
const char *SQLiteClassBuilder::CreateHeaderForAllTables = "%CreateHeaderForAllTables%";
341+
const char *SQLiteClassBuilder::CreateHeaderForAllTables = "%_CreateHeaderForAllTables_%";
328342

329343
std::string SQLiteClassBuilder::GetType(const char* str_org)
330344
{
@@ -459,7 +473,7 @@ namespace sqlite3pp
459473
{
460474
std::ios_base::openmode openMode = m_AppendTableToHeader ? std::ios_base::out | std::ios_base::app : std::ios_base::out;
461475
ClassName = m_options.h.header_prefix + TableName + m_options.h.header_postfix;
462-
const std::string HeaderFileName = m_options.h.dest_folder + ClassName + ".h";
476+
const std::string HeaderFileName = m_options.h.dest_folder + ClassName + "." + m_options.h.file_type;
463477
myfile.open(HeaderFileName.c_str(), openMode);
464478
if (!myfile.is_open())
465479
return false;
@@ -476,7 +490,7 @@ namespace sqlite3pp
476490
FirstColumnName = "ColumnFoo";
477491
if (LastColumnName.empty())
478492
LastColumnName = "ColumnWiget";
479-
myfile << "Example Usage:" << std::endl;
493+
myfile << "Example Usage:\t\t(Using sqlite3pp::Table container)" << std::endl;
480494
myfile << "\t// Exampel #1\n\t\tsqlite3pp::setGlobalDB(\"mydatabase.db\");" << std::endl;
481495
myfile << "\t\tsqlite3pp::Table<" << ClassName << "> my_tbl;\n\t\tfor (auto row : my_tbl)\n\t\t\tstd::wcout << row << std::endl;\n" << std::endl;
482496

@@ -489,6 +503,8 @@ namespace sqlite3pp
489503
myfile << "#ifndef " << HeaderUpper << std::endl;
490504
myfile << "#define " << HeaderUpper << std::endl;
491505
myfile << m_options.s.str_include << std::endl;
506+
if (m_options.h.header_include.size())
507+
myfile << "#include \"" << m_options.h.header_include << "\"" << std::endl;
492508

493509
return true;
494510
}
@@ -499,8 +515,14 @@ namespace sqlite3pp
499515
m_ClassNames.clear();
500516
m_options = strtype;
501517
const std::string OrgPrefix = m_options.h.header_prefix;
502-
using SQLiteMaster = Table<sqlite_master>;
518+
using SQLiteMaster = TableOStream<sqlite_master>;
503519
SQLiteMaster tbl(m_db, WhereClauseArg(T_("where (type = 'table' or type = 'view') ") + sql_base::to_tstring(AndWhereClause)) );
520+
521+
// ToDo: Comment out the next 2 lines of code after testing
522+
std::ofstream ofs("data.csv", std::ofstream::out);
523+
ofs << tbl;
524+
std::cout << tbl;
525+
504526
for (auto t : tbl)
505527
{
506528
m_options.h.header_prefix = OrgPrefix + t.type + "_";
@@ -594,6 +616,7 @@ namespace sqlite3pp
594616

595617
bool SQLiteClassBuilder::ProcessClassCreation(const std::string& TableName, std::string QueryStr)
596618
{
619+
const char* CommentSection = "////////////////////////////////////////////////////////////////////////////////////////////";
597620
if (QueryStr.empty())
598621
QueryStr = "SELECT * FROM \"" + TableName + "\"";
599622
std::shared_ptr < sqlite3pp::query> qry(sql_base::CreateQuery(m_db, QueryStr));
@@ -626,26 +649,49 @@ namespace sqlite3pp
626649

627650
if (!m_options.m.exclude_table_interface)
628651
{
652+
if (!m_options.m.exclude_comments)
653+
myfile << "\n\t// Constructors" << std::endl;
654+
// These constructors are only useful if method setData is created.
655+
myfile << "\t" << ClassName << "() {}"; // Allow default constructor to still work
656+
if (!m_options.m.exclude_comments)
657+
myfile << " // Default constructor";
658+
myfile << std::endl;
659+
myfile << "\ttemplate <class T> " << ClassName << "(const T &t) { setData(t); }"; // This constructor allows data transfer from different tables/views having same data types and column names
660+
if (!m_options.m.exclude_comments)
661+
myfile << " // Allows data input from different (or same) tables/views having the same data types and column names";
662+
myfile << std::endl;
663+
629664
if (!m_options.m.exclude_comments)
630665
myfile << "\n\t// getTableName, getColumnNames, getSelecColumnNames, and getStreamData are required for sqlite3pp::Table template class" << std::endl;
631-
// Create getTableName member function. It's needed for sqlite3pp::Table template class
666+
667+
// Create getTableName member function. Needed for sqlite3pp::Table template class
632668
myfile << "\tstatic StrType getTableName() { return " << m_options.s.str_pre << " \"" << TableName << "\" " << m_options.s.str_post << "; }" << std::endl;
633-
// Create getColumnNames member function. It's needed for sqlite3pp::Table template class
669+
670+
// Create getColumnNames member function. Needed for sqlite3pp::Table template class
634671
myfile << "\tstatic StrType getColumnNames() { return " << m_options.s.str_pre << " \"";
635672
for (auto c : columns_with_comma)
636673
myfile << c.second << c.first;
637674
myfile << "\"" << m_options.s.str_post << "; }" << std::endl;
638-
// Create getSelecColumnNames member function. It's needed for sqlite3pp::Table template class
675+
676+
// Create getSelecColumnNames member function. Needed for sqlite3pp::Table template class
639677
myfile << "\tstatic StrType getSelecColumnNames() { return " << m_options.s.str_pre << " \"";
640678
for (auto c : columns_with_comma)
641679
myfile << c.second << "\\\"" << c.first<< "\\\"" ;
642680
myfile << "\"" << m_options.s.str_post << "; }" << std::endl;
643-
// Create getStreamData member function. It's needed for sqlite3pp::Table template class
681+
682+
// Create getStreamData member function. Needed for sqlite3pp::Table template class
644683
myfile << "\ttemplate<class T> void getStreamData( T q ) { q.getter() ";
645684
for (auto c : columns)
646685
myfile << " >> " << c.first;
647686
myfile << ";}" << std::endl;
648687

688+
// Create setData member function. Used to transfer data from different tables/views having same data types and column names
689+
myfile << "\ttemplate <class T> void setData(const T &t) // Used to transfer data from different tables/views having same data types and column names\n\t{" << std::endl;
690+
for (auto c : columns)
691+
myfile << "\t\t" << c.first << " = t.get_" << c.first << "();" << std::endl;
692+
myfile << "\t}" << std::endl;
693+
694+
649695
// Miscellaneous functions
650696
if (!m_options.m.exclude_comments)
651697
myfile << "\n\t// Miscellaneous functions" << std::endl;
@@ -682,11 +728,12 @@ namespace sqlite3pp
682728
for (auto c : columns)
683729
myfile << "\t" << c.second << " " << c.first << ";" << std::endl;
684730

685-
const char* OperatorStreamComment = "// Optional logic for operator<<(). Set exclude_ostream_operator to true to exclude operator<<() logic when creating this class through SQLiteClassBuilder.\n";
731+
const std::string OperatorStreamComment1 = "/* sqlite3pp::TableOStream container interface.\n\tFunctions OStream(), operator<<(), and Delimiter() are required when using the sqlite3pp::TableOStream container.\n\tExample Usage:\t\t(Using sqlite3pp::TableOStream container)\n\t\t\tTableOStream<" + ClassName + "> tbl(DbFileNameArg(\"mydatabase.db\"));\n\t\t\ttbl.setDelimit(\"|\"); // Change delimiter\n\t\t\tstd::cout << tbl; // Send data to screen with the changed delimiter\n\n\t\t\tstd::ofstream ofs (\"data.csv\", std::ofstream::out);\n\t\t\ttbl.setDelimit(\",\"); // Change delimiter\n\t\t\tofs << tbl; // Write data to a CSV file using the changed \",\" delimiter.\n\n\t\t\ttbl.out(std::cout); // Send data to screen using out() member function.\n\tTo exclude TableOStream interface, set exclude_ostream_operator to true when creating this class using SQLiteClassBuilder.\n\t*/\n";
732+
const char* OperatorStreamComment2 = "// sqlite3pp::TableOStream container interface.\n";
686733
if (m_options.m.exclude_ostream_operator != true)
687734
{
688735
if (!m_options.m.exclude_comments)
689-
myfile << "\n\t" << OperatorStreamComment;
736+
myfile << "\n\t" <<CommentSection << "\n\t" << OperatorStreamComment1;
690737
////////////////////////////////////////////////////////////////////////////////////////////
691738
// Create function OStream
692739
myfile << "\ttemplate<class T> T& OStream(T& t) const\n\t{\n\t\tt.os";
@@ -707,6 +754,8 @@ namespace sqlite3pp
707754
myfile << "\tfriend std::wostream& operator<<(std::wostream& os, const " << ClassName << "& t);" << std::endl;
708755
// Create Delimit member function. It's needed for operator<<
709756
myfile << "\tstatic StrType Delimiter() { return " << m_options.s.str_pre << " \"" << m_options.m.delimiter << "\" " << m_options.s.str_post << "; }" << std::endl;
757+
if (!m_options.m.exclude_comments)
758+
myfile << "\t" << CommentSection << std::endl;
710759
}
711760

712761

@@ -717,7 +766,7 @@ namespace sqlite3pp
717766
if (m_options.m.exclude_ostream_operator != true)
718767
{
719768
if (!m_options.m.exclude_comments)
720-
myfile << OperatorStreamComment;
769+
myfile << OperatorStreamComment2;
721770
myfile << "std::ostream& operator<<(std::ostream& os, const " << ClassName << "& t) { sqlite3pp::ostream_a o(os, t.Delimiter()); return t.OStream(o).os; }" << std::endl;
722771
myfile << "std::wostream& operator<<(std::wostream& os, const " << ClassName << "& t) { sqlite3pp::ostream_w o(os, t.Delimiter()); return t.OStream(o).os; }" << std::endl;
723772
}

0 commit comments

Comments
 (0)