Skip to content

Commit b9aaba4

Browse files
Wrapped double quotes when querying columns and tables
1 parent d622000 commit b9aaba4

File tree

2 files changed

+163
-56
lines changed

2 files changed

+163
-56
lines changed

sqlite3pp_ez.cpp

Lines changed: 87 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ namespace sqlite3pp
5757
return sqlite3pp::to_string( src.c_str() );
5858
}
5959

60+
#ifdef _UNICODE
61+
std::wstring sql_base::to_tstring(const std::string &src)
62+
{
63+
return to_wstring(src);
64+
}
65+
#else
66+
std::string sql_base::to_tstring(const std::wstring &src)
67+
{
68+
return to_string(src);
69+
}
70+
#endif // _UNICODE
71+
6072
int database::connect( wchar_t const * dbname, int flags, const wchar_t * vfs )
6173
{
6274
if ( !borrowing_ )
@@ -212,6 +224,7 @@ namespace sqlite3pp
212224
using StrType = std::string;
213225
static StrType getTableName() { return "sqlite_master"; }
214226
static StrType getColumnNames() { return "type, name, tbl_name, rootpage, sql"; }
227+
static StrType getSelecColumnNames() { return "type, name, tbl_name, rootpage, sql"; }
215228
template<class T> void getStreamData(T q) { q.getter() >> type >> name >> tbl_name >> rootpage >> sql; }
216229
static int getColumnCount() { return 5; }
217230
public:
@@ -228,22 +241,25 @@ namespace sqlite3pp
228241
const StrOptions SQLiteClassBuilder::strOpt_sql_tstring = { "sqlite3pp::tstring", "T_(", ")", "#include \"sqlite3pp_ez.h\"" };
229242
const StrOptions SQLiteClassBuilder::strOpt_sql_tstring_T = { "sqlite3pp::tstring", "_T(", ")", "#include \"sqlite3pp_ez.h\"" };
230243
// Predefined MiscOptions for common settings
231-
const MiscOptions SQLiteClassBuilder::MiscOpt_max = { ",", false, false, false, false, false, false };
232-
const MiscOptions SQLiteClassBuilder::MiscOpt_min = { ",", true, true, true, true, true, false, false };
233-
const MiscOptions SQLiteClassBuilder::MiscOpt_var = { ",", true, true, true, true, true, true, false };
244+
const MiscOptions SQLiteClassBuilder::MiscOpt_max = { ",", false, false, false, false, false, false, false, false, false };
245+
const MiscOptions SQLiteClassBuilder::MiscOpt_min = { ",", true, true, true, true, true, false, false, true, true };
246+
const MiscOptions SQLiteClassBuilder::MiscOpt_var = { ",", true, true, true, true, true, true, false, true, true };
234247
// Default settings for HeaderOpt
235248
const HeaderOpt SQLiteClassBuilder::HeaderDefaultOpt = { "SQL\\", "sql_", "" };
236249

237250
const char *SQLiteClassBuilder::Nill = "#NILL#";
238251
const char *SQLiteClassBuilder::CreateHeaderForAllTables = "%CreateHeaderForAllTables%";
239252

240-
std::string SQLiteClassBuilder::GetType(const char* str)
253+
std::string SQLiteClassBuilder::GetType(const char* str_org)
241254
{
242255
const std::string DefaultType = "Text";
243-
if (!str)
256+
if (!str_org)
244257
{
245258
return DefaultType;
246259
}
260+
char str[99] = { 0 };
261+
strcpy_s(str, str_org);
262+
_strupr_s(str);
247263
// There's no practical method for handling blob or clob other than the Blob and Clob type, so don't even include them in an option to declare them any other way.
248264
if (strcmp("BLOB", str) == 0)
249265
return "Blob";
@@ -337,11 +353,16 @@ namespace sqlite3pp
337353
return st.st_mode & S_IFDIR;
338354
}
339355

340-
void SQLiteClassBuilder::Init(const std::string & TableOrView_name, const std::string & PostFixWhereClause, const StrOptions & stroptions, const MiscOptions & miscoptions, const HeaderOpt & headeropt)
356+
TblClassOptions SQLiteClassBuilder::Init(const StrOptions & stroptions, const MiscOptions & miscoptions, const HeaderOpt & headeropt)
357+
{
358+
TblClassOptions option = { stroptions, miscoptions, headeropt };
359+
return option;
360+
}
361+
362+
void SQLiteClassBuilder::Init(const std::string & TableOrView_name, const std::string & WhereClause)
341363
{
342-
m_options = { stroptions , miscoptions , headeropt};
343364
if (TableOrView_name == CreateHeaderForAllTables)
344-
CreateAllHeaders(m_options, PostFixWhereClause);
365+
CreateAllHeaders(m_options, WhereClause);
345366
else if (!TableOrView_name.empty() && TableOrView_name != Nill)
346367
CreateHeader(TableOrView_name);
347368
}
@@ -351,9 +372,9 @@ namespace sqlite3pp
351372
m_db.disconnect();
352373
}
353374

354-
bool SQLiteClassBuilder::CreateAllHeaders(const std::string &PostFixWhereClause)
375+
bool SQLiteClassBuilder::CreateAllHeaders(const std::string &WhereClause)
355376
{
356-
return CreateAllHeaders(m_options, PostFixWhereClause);
377+
return CreateAllHeaders(m_options, WhereClause);
357378
}
358379

359380
bool SQLiteClassBuilder::CreateHeaderPrefix(const std::string& TableName, std::ofstream &myfile, std::string& ClassName, std::string& HeaderUpper, bool AppendToVect)
@@ -378,13 +399,14 @@ namespace sqlite3pp
378399
return true;
379400
}
380401

381-
bool SQLiteClassBuilder::CreateAllHeaders(const TblClassOptions &strtype, const std::string &PostFixWhereClause)
402+
bool SQLiteClassBuilder::CreateAllHeaders(const TblClassOptions &strtype, const std::string &WhereClause)
382403
{
383404
m_HeadersCreated.clear();
405+
m_ClassNames.clear();
384406
m_options = strtype;
385407
const std::string OrgPrefix = m_options.h.header_prefix;
386408
using SQLiteMaster = Table<sqlite_master>;
387-
SQLiteMaster tbl(m_db, SQLiteMaster::WhereClauseArg("where (type = 'table' or type = 'view') " + PostFixWhereClause));
409+
SQLiteMaster tbl(m_db, SQLiteMaster::WhereClauseArg("where (type = 'table' or type = 'view') " + WhereClause));
388410
for (auto t : tbl)
389411
{
390412
m_options.h.header_prefix = OrgPrefix + t.type + "_";
@@ -396,8 +418,44 @@ namespace sqlite3pp
396418
if (CreateHeaderPrefix("All_Headers", myfile, ClassName, HeaderUpper, false))
397419
{
398420
for (auto s : m_HeadersCreated)
399-
{
400421
myfile << "#include \"" << s << "\"" << std::endl;
422+
if (!m_options.m.exclude_main_hdr_example)
423+
{
424+
myfile << "\n" << std::endl;
425+
if (!m_options.m.exclude_comment_out_exampl)
426+
myfile << "/*" << std::endl;
427+
if (!m_options.m.exclude_comments)
428+
{
429+
myfile << "// This example code can be used to test and validate all tables." << std::endl;
430+
myfile << "// Example Usage:" << std::endl;
431+
myfile << "// \t\tqlite3pp::setGlobalDB(\"mydatabase.db\")" << std::endl;
432+
myfile << "// \t\tsqlite3pp::testAllTables();" << std::endl;
433+
myfile << "// Warning: testPopulatingAllTables and testAllTables may take a very long time on a database with a lot of content." << std::endl;
434+
}
435+
myfile << "#include <map>\n#include <memory>\nnamespace sqlite3pp\n{" << std::endl;
436+
437+
// Function to create all table instances
438+
if (!m_options.m.exclude_comments)
439+
myfile << "\t// Function to test populating all tables & views." << std::endl;
440+
myfile << "\tstd::map< std::string, std::shared_ptr<sqlite3pp::TableBase> > testPopulatingAllTables()\n\t{" << std::endl;
441+
myfile << "\t\tstd::map< std::string, std::shared_ptr < sqlite3pp::TableBase>> Tables;" << std::endl;
442+
for (auto s : m_ClassNames)
443+
myfile << "\t\tTables[\"" << s << "\"] = std::shared_ptr<sqlite3pp::TableBase>(new sqlite3pp::Table<" << s << ">());" << std::endl;
444+
myfile << "\t\treturn Tables;\n\t}" << std::endl;
445+
446+
// Function to test all tables
447+
myfile << std::endl;
448+
if (!m_options.m.exclude_comments)
449+
myfile << "\t// Function to test displaying content of all tables & views." << std::endl;
450+
myfile << "\tvoid testAllTables()\n\t{" << std::endl;
451+
myfile << "\t\tstd::map< std::string, std::shared_ptr < sqlite3pp::TableBase>> myTables = sqlite3pp::testPopulatingAllTables();" << std::endl;
452+
myfile << "\t\tfor (auto t : myTables)\n\t\t\tt.second->out(std::wcout);" << std::endl;
453+
myfile << "\t}" << std::endl;
454+
455+
myfile << "}" << std::endl;
456+
if (!m_options.m.exclude_comment_out_exampl)
457+
myfile << "*/" << std::endl;
458+
myfile << "\n" << std::endl;
401459
}
402460
myfile << "\n#endif // !" << HeaderUpper << std::endl;
403461
myfile.close();
@@ -415,16 +473,23 @@ namespace sqlite3pp
415473
return false;
416474
}
417475

418-
bool SQLiteClassBuilder::CreateHeader(const std::string& TableName, std::string QueryStr)
476+
bool SQLiteClassBuilder::CreateHeader(const std::string& TableName, const TblClassOptions *strtype, std::string QueryStr)
419477
{
420478
m_HeadersCreated.clear();
479+
m_ClassNames.clear();
480+
TblClassOptions options;
481+
if (strtype)
482+
{
483+
options = m_options;
484+
m_options = *strtype;
485+
}
421486
return ProcessClassCreation(TableName, QueryStr);
422487
}
423488

424489
bool SQLiteClassBuilder::ProcessClassCreation(const std::string& TableName, std::string QueryStr)
425490
{
426491
if (QueryStr.empty())
427-
QueryStr = "SELECT * FROM " + TableName;
492+
QueryStr = "SELECT * FROM \"" + TableName + "\"";
428493
sqlite3pp::query qry(m_db, QueryStr.c_str());
429494
std::vector<std::pair<std::string, std::string> > columns;
430495
std::vector<std::pair<std::string, std::string> > columns_with_comma;
@@ -438,7 +503,7 @@ namespace sqlite3pp
438503
std::string ClassName, HeaderUpper;
439504
if (!CreateHeaderPrefix(TableName, myfile, ClassName, HeaderUpper))
440505
return false;
441-
506+
m_ClassNames.push_back(ClassName);
442507
////////////////////////////////////////////////////////////////////////////////////////////
443508
// Create Table/View class, and create a define type for strings
444509
myfile << "\nclass " << ClassName << ": public sqlite3pp::sql_base\n{\npublic:" << std::endl;
@@ -447,14 +512,19 @@ namespace sqlite3pp
447512
if (!m_options.m.exclude_table_interface)
448513
{
449514
if (!m_options.m.exclude_comments)
450-
myfile << "\n\t// getTableName, getColumnNames, and getStreamData are required for sqlite3pp::Table template class" << std::endl;
515+
myfile << "\n\t// getTableName, getColumnNames, getSelecColumnNames, and getStreamData are required for sqlite3pp::Table template class" << std::endl;
451516
// Create getTableName member function. It's needed for sqlite3pp::Table template class
452517
myfile << "\tstatic StrType getTableName() { return " << m_options.s.str_pre << " \"" << TableName << "\" " << m_options.s.str_post << "; }" << std::endl;
453518
// Create getColumnNames member function. It's needed for sqlite3pp::Table template class
454519
myfile << "\tstatic StrType getColumnNames() { return " << m_options.s.str_pre << " \"";
455520
for (auto c : columns_with_comma)
456521
myfile << c.second << c.first;
457522
myfile << "\"" << m_options.s.str_post << "; }" << std::endl;
523+
// Create getSelecColumnNames member function. It's needed for sqlite3pp::Table template class
524+
myfile << "\tstatic StrType getSelecColumnNames() { return " << m_options.s.str_pre << " \"";
525+
for (auto c : columns_with_comma)
526+
myfile << c.second << "\\\"" << c.first<< "\\\"" ;
527+
myfile << "\"" << m_options.s.str_post << "; }" << std::endl;
458528
// Create getStreamData member function. It's needed for sqlite3pp::Table template class
459529
myfile << "\ttemplate<class T> void getStreamData( T q ) { q.getter() ";
460530
for (auto c : columns)

0 commit comments

Comments
 (0)