Skip to content

Commit 1a751f7

Browse files
Finished enhancement to the code to allow it to handle tables and fields having spaces in the name
1 parent f89656f commit 1a751f7

File tree

1 file changed

+47
-31
lines changed

1 file changed

+47
-31
lines changed

sqlite3pp_ez.cpp

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ namespace sqlite3pp
10351035

10361036
if (strcmp("INTEGER", str) == 0 || strcmp("INT", str) == 0 || strcmp("TINYINT", str) == 0 || strcmp("SMALLINT", str) == 0 || strcmp("MEDIUMINTSMALLINT", str) == 0 || strcmp("BIGINT", str) == 0 || strcmp("UNSIGNED BIG INT", str) == 0 || strcmp("INT2", str) == 0 || strcmp("INT8", str) == 0)
10371037
return "int";
1038-
if (strcmp("REAL", str) == 0 || strcmp("DOUBLE", str) == 0 || strcmp("DOUBLE PRECISION", str) == 0 || strcmp("FLOAT", str) == 0 || strncmp("DECIMAL", str, 7) == 0 || strcmp("BOOLEANL", str) == 0 || strcmp("BOOLEAN", str) == 0 || strcmp("DATE", str) == 0 || strcmp("DATETIME", str) == 0 || strcmp("NUMERIC", str) == 0)
1038+
if (strcmp("REAL", str) == 0 || strcmp("DOUBLE", str) == 0 || strcmp("DOUBLE PRECISION", str) == 0 || strcmp("FLOAT", str) == 0 || strncmp("DECIMAL", str, 7) == 0 || strcmp("BOOLEANL", str) == 0 || strcmp("BOOLEAN", str) == 0 || strcmp("BOOL", str) == 0 || strcmp("DATE", str) == 0 || strcmp("DATETIME", str) == 0 || strcmp("NUMERIC", str) == 0 || strcmp("NUMBER", str) == 0)
10391039
return "double";
10401040

10411041
if (m_options.m.use_basic_types_only)
@@ -1063,17 +1063,17 @@ namespace sqlite3pp
10631063
return "Smallint";
10641064
if (strcmp("MEDIUMINTSMALLINT", str) == 0)
10651065
return "Mediumint";
1066-
if (strcmp("BOOLEAN", str) == 0 || strcmp("BOOLEANL", str) == 0)
1066+
if (strcmp("BOOLEAN", str) == 0 || strcmp("BOOLEANL", str) == 0 || strcmp("BOOL", str) == 0)
10671067
return "Boolean";
10681068
if (strcmp("BIGINT", str) == 0)
10691069
return "Bigint";
1070-
if (strcmp("UNSIGNED BIG INT", str) == 0)
1070+
if (strcmp("UNSIGNED BIG INT", str) == 0 || strcmp("UBIGINT", str) == 0)
10711071
return "UBigint";
10721072
if (strcmp("DATE", str) == 0)
10731073
return "Date";
10741074
if (strcmp("DATETIME", str) == 0)
10751075
return "Datetime";
1076-
if (str_type.find("NUMERIC") == 0)
1076+
if (str_type.find("NUMERIC") == 0 || str_type.find("NUMBER") == 0)
10771077
return "Numeric";
10781078
if (str_type.find("DECIMAL") == 0)
10791079
return "Decimal";
@@ -1153,6 +1153,22 @@ namespace sqlite3pp
11531153
static const char TopHeaderCommnetsPrt1[] = "/* This file was automatically generated using [Sqlite3pp_EZ].\nSqlite3pp_EZ Copyright (C) 2025 David Maisonave (http::\\www.axter.com)";
11541154
static const char TopHeaderCommnetsPrt2[] = "For more details see https://github.com/David-Maisonave/sqlite3pp_EZ\n*/";
11551155
const std::vector<std::pair<std::string, std::string> > SQLiteClassBuilder::columns_dummy;
1156+
1157+
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
1158+
if (from.empty())
1159+
return;
1160+
size_t start_pos = 0;
1161+
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
1162+
str.replace(start_pos, from.length(), to);
1163+
start_pos += to.length(); // Move past the replaced text
1164+
}
1165+
}
1166+
std::string GetValidFuncName(std::string name)
1167+
{
1168+
//ToDo: Use regex to make sure all values are AlphaNum
1169+
replaceAll(name, " ", "__");
1170+
return name;
1171+
}
11561172

11571173
bool SQLiteClassBuilder::CreateHeaderPrefix(const std::string& TableName, std::ofstream &myfile,
11581174
std::string& ClassName, std::string& HeaderUpper, std::string FirstColumnName, std::string LastColumnName,
@@ -1192,9 +1208,9 @@ namespace sqlite3pp
11921208
myfile << "\t// Example #1\n\t\tsqlite3pp::setGlobalDB(\"myDatabase.db\");" << std::endl;
11931209
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;
11941210

1195-
myfile << "\t// Example #2\n\t\tfor (int i = 0; i < my_tbl.size(); ++i)\n\t\t\tstd::wcout << my_tbl[i].get_" << FirstColumnName << "() << std::endl;\n" << std::endl;
1211+
myfile << "\t// Example #2\n\t\tfor (int i = 0; i < my_tbl.size(); ++i)\n\t\t\tstd::wcout << my_tbl[i].get_" << GetValidFuncName(FirstColumnName) << "() << std::endl;\n" << std::endl;
11961212

1197-
myfile << "\t// Example #3\n\t\tfor (auto r = my_tbl.begin(); r != my_tbl.end(); ++r)\n\t\t\tstd::wcout << r->get_" << LastColumnName << "() << std::endl;\n" << std::endl;
1213+
myfile << "\t// Example #3\n\t\tfor (auto r = my_tbl.begin(); r != my_tbl.end(); ++r)\n\t\t\tstd::wcout << r->get_" << GetValidFuncName(LastColumnName) << "() << std::endl;\n" << std::endl;
11981214
if (columns.size() > 0)
11991215
{
12001216
std::string outType = "std::cout";
@@ -1212,29 +1228,29 @@ namespace sqlite3pp
12121228
myfile << "\n\t\tfor(auto row : my_tbl)\n";
12131229
myfile << "\t\t\t" << outType;
12141230
for (auto& c : columns)
1215-
myfile << " << row.get_" << c.first << "()" << ColumnSep;
1231+
myfile << " << row.get_" << GetValidFuncName(c.first) << "()" << ColumnSep;
12161232
myfile << " << std::endl;" << std::endl;
12171233

12181234
myfile << "\n\t\t// Example#4b -- C++ style iteration";
12191235
myfile << "\n\t\tfor (auto row = my_tbl.begin(); row != my_tbl.end(); ++row) \n";
12201236
myfile << "\t\t\t" << outType;
12211237
for (auto& c : columns)
1222-
myfile << " << row->get_" << c.first << "()" << ColumnSep;
1238+
myfile << " << row->get_" << GetValidFuncName(c.first) << "()" << ColumnSep;
12231239
myfile << " << std::endl;" << std::endl;
12241240

12251241
myfile << "\n\t\t// Example#4c -- C style iteration";
12261242
myfile << "\n\t\tfor (int row = 0; row < my_tbl.size(); ++row) \n";
12271243
myfile << "\t\t\t" << outType;
12281244
for (auto& c : columns)
1229-
myfile << " << my_tbl[row].get_" << c.first << "()" << ColumnSep;
1245+
myfile << " << my_tbl[row].get_" << GetValidFuncName(c.first) << "()" << ColumnSep;
12301246
myfile << " << std::endl;" << std::endl;
12311247
}
12321248
myfile << TopHeaderCommnetsPrt2 << std::endl;
12331249

12341250
}
12351251
// Add includes needed to support specified m_options.str_type
1236-
myfile << "#ifndef " << HeaderUpper << std::endl;
1237-
myfile << "#define " << HeaderUpper << std::endl;
1252+
myfile << "#ifndef " << GetValidFuncName(HeaderUpper) << std::endl;
1253+
myfile << "#define " << GetValidFuncName(HeaderUpper) << std::endl;
12381254
const std::string AdditionalInclude = "#include \"" + m_options.h.header_include + "\"";
12391255
if (m_options.s.str_include.size() && m_options.s.str_include != AdditionalInclude &&
12401256
(m_options.s.str_include != strOpt_sql_tstring.str_include || (m_options.h.header_include != HeadersCreatedSqlDir.header_include && m_options.h.header_include != HeadersCreatedBaseDir.header_include) ))
@@ -1306,7 +1322,7 @@ namespace sqlite3pp
13061322
myfile << "*/" << std::endl;
13071323
myfile << "\n" << std::endl;
13081324
}
1309-
myfile << "\n#endif // !" << HeaderUpper << std::endl;
1325+
myfile << "\n#endif // !" << GetValidFuncName(HeaderUpper) << std::endl;
13101326
myfile.close();
13111327
V_COUT(DETAIL, "Finish creating Master_Header file.");
13121328
}
@@ -1401,10 +1417,10 @@ namespace sqlite3pp
14011417
std::string ClassName, HeaderUpper;
14021418
if (!CreateHeaderPrefix(TableName, myfile, ClassName, HeaderUpper, FirstColumnName, LastColumnName, true, columns))
14031419
return false;
1404-
m_ClassNames.push_back(ClassName);
1420+
m_ClassNames.push_back(GetValidFuncName(ClassName));
14051421
////////////////////////////////////////////////////////////////////////////////////////////
14061422
// Create Table/View class
1407-
myfile << "\nclass " << ClassName << ": public sqlite3pp::sql_base\n{" << std::endl;
1423+
myfile << "\nclass " << GetValidFuncName(ClassName) << ": public sqlite3pp::sql_base\n{" << std::endl;
14081424

14091425
if (!m_options.m.exclude_table_interface)
14101426
{
@@ -1416,7 +1432,7 @@ namespace sqlite3pp
14161432

14171433
// Define data member variables associated with the table/view
14181434
for (auto& c : columns)
1419-
myfile << "\t" << c.second << " " << c.first << InitializeValue(c.second) << ";" << std::endl;
1435+
myfile << "\t" << c.second << " " << GetValidFuncName(c.first) << InitializeValue(c.second) << ";" << std::endl;
14201436

14211437
myfile << "\npublic:" << std::endl;
14221438
// Create a define type for strings
@@ -1426,11 +1442,11 @@ namespace sqlite3pp
14261442
if (!m_options.m.exclude_comments)
14271443
myfile << "\t// Constructors" << std::endl;
14281444
// These constructors are only useful if method setData is created.
1429-
myfile << "\t" << ClassName << "() {}"; // Allow default constructor to still work
1445+
myfile << "\t" << GetValidFuncName(ClassName) << "() {}"; // Allow default constructor to still work
14301446
if (!m_options.m.exclude_comments)
14311447
myfile << " // Default constructor";
14321448
myfile << std::endl;
1433-
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
1449+
myfile << "\ttemplate <class T> " << GetValidFuncName(ClassName) << "(const T &t) { setData(t); }"; // This constructor allows data transfer from different tables/views having same data types and column names
14341450
if (!m_options.m.exclude_comments)
14351451
myfile << " // Allows data input from different (or same) tables/views having the same data types and column names";
14361452
myfile << std::endl;
@@ -1444,7 +1460,7 @@ namespace sqlite3pp
14441460
// Create getColumnNames member function. Needed for sqlite3pp::Table template class
14451461
myfile << "\tstatic StrType getColumnNames() { return " << m_options.s.str_pre << "\"";
14461462
for (auto& c : columns_with_comma)
1447-
myfile << c.second << c.first;
1463+
myfile << c.second << "\\\"" << c.first << "\\\"";
14481464
myfile << "\"" << m_options.s.str_post << "; }" << std::endl;
14491465

14501466
// Create getSelectColumnNames member function. Needed for sqlite3pp::Table template class
@@ -1459,21 +1475,21 @@ namespace sqlite3pp
14591475
for (auto& c : columns)
14601476
{
14611477
myfile << "\n\t\tstrtype += " << m_options.s.str_pre << "\"" << commaDel << "'\"" << m_options.s.str_post
1462-
<< " + " << m_options.s.str_tostr << "( " << c.first << ") + " << m_options.s.str_pre << "\"'\"" << m_options.s.str_post << ";";
1478+
<< " + " << m_options.s.str_tostr << "( " << GetValidFuncName(c.first) << ") + " << m_options.s.str_pre << "\"'\"" << m_options.s.str_post << ";";
14631479
commaDel = ",";
14641480
}
14651481
myfile << "\n\t\treturn strtype;\n\t}" << std::endl;
14661482

14671483
// Create getStreamData member function. Needed for sqlite3pp::Table template class
14681484
myfile << "\ttemplate<class T> void getStreamData( T q ) { q.getter() ";
14691485
for (auto& c : columns)
1470-
myfile << " >> " << c.first;
1486+
myfile << " >> " << GetValidFuncName(c.first);
14711487
myfile << ";}" << std::endl;
14721488

14731489
// Create setData member function. Used to transfer data from different tables/views having same data types and column names
14741490
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;
14751491
for (auto& c : columns)
1476-
myfile << "\t\t" << c.first << " = t.get_" << c.first << "();" << std::endl;
1492+
myfile << "\t\t" << GetValidFuncName(c.first) << " = t.get_" << GetValidFuncName(c.first) << "();" << std::endl;
14771493
myfile << "\t}" << std::endl;
14781494

14791495

@@ -1492,7 +1508,7 @@ namespace sqlite3pp
14921508
myfile << ", which allows read-only access to protected member variables";
14931509
myfile << "." << std::endl;
14941510
for (auto& c : columns)
1495-
myfile << "\tconst " << c.second << "& get_" << c.first << "() const {return " << c.first << ";}" << std::endl;
1511+
myfile << "\tconst " << c.second << "& get_" << GetValidFuncName(c.first) << "() const {return " << GetValidFuncName(c.first) << ";}" << std::endl;
14961512
}
14971513

14981514
// Define set function for each data member variable.
@@ -1501,10 +1517,10 @@ namespace sqlite3pp
15011517
if (!m_options.m.exclude_comments)
15021518
myfile << "\n\t// A set_ function for each field in the table." << std::endl;
15031519
for (auto& c : columns)
1504-
myfile << "\tvoid set_" << c.first << "(const " << c.second << "& data__) {" << c.first << " = data__;}" << std::endl;
1520+
myfile << "\tvoid set_" << GetValidFuncName(c.first) << "(const " << c.second << "& data__) {" << GetValidFuncName(c.first) << " = data__;}" << std::endl;
15051521
}
15061522

1507-
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";
1523+
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<" + GetValidFuncName(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";
15081524
const char* OperatorStreamComment2 = "// sqlite3pp::TableOStream container interface.\n";
15091525
if (m_options.m.exclude_ostream_operator != true)
15101526
{
@@ -1517,17 +1533,17 @@ namespace sqlite3pp
15171533
for (auto& c : columns)
15181534
{
15191535
if (IsStrType(c.second.c_str()))
1520-
myfile << delimiter_tmp << " << t.str(" << c.first << ")";
1536+
myfile << delimiter_tmp << " << t.str(" << GetValidFuncName(c.first) << ")";
15211537
else
1522-
myfile << delimiter_tmp << " << " << c.first;
1538+
myfile << delimiter_tmp << " << " << GetValidFuncName(c.first);
15231539
if (delimiter_tmp.empty())
15241540
delimiter_tmp = " << t.d";
15251541
}
15261542
myfile << ";\n\t\treturn t;\n\t}" << std::endl;
15271543
////////////////////////////////////////////////////////////////////////////////////////////
15281544
// Declare operator<< friends
1529-
myfile << "\tfriend std::ostream& operator<<(std::ostream& os, const " << ClassName << "& t);" << std::endl;
1530-
myfile << "\tfriend std::wostream& operator<<(std::wostream& os, const " << ClassName << "& t);" << std::endl;
1545+
myfile << "\tfriend std::ostream& operator<<(std::ostream& os, const " << GetValidFuncName(ClassName) << "& t);" << std::endl;
1546+
myfile << "\tfriend std::wostream& operator<<(std::wostream& os, const " << GetValidFuncName(ClassName) << "& t);" << std::endl;
15311547
// Create Delimit member function. It's needed for operator<<
15321548
myfile << "\tstatic StrType Delimiter() { return " << m_options.s.str_pre << "\"" << m_options.m.delimiter << "\" " << m_options.s.str_post << "; }" << std::endl;
15331549
if (!m_options.m.exclude_comments)
@@ -1543,15 +1559,15 @@ namespace sqlite3pp
15431559
{
15441560
if (!m_options.m.exclude_comments)
15451561
myfile << OperatorStreamComment2;
1546-
myfile << "inline std::ostream& operator<<(std::ostream& os, const " << ClassName << "& t) { sqlite3pp::ostream_a o(os, t.Delimiter()); return t.OStream(o).os; }" << std::endl;
1547-
myfile << "inline std::wostream& operator<<(std::wostream& os, const " << ClassName << "& t) { sqlite3pp::ostream_w o(os, t.Delimiter()); return t.OStream(o).os; }" << std::endl;
1562+
myfile << "inline std::ostream& operator<<(std::ostream& os, const " << GetValidFuncName(ClassName) << "& t) { sqlite3pp::ostream_a o(os, t.Delimiter()); return t.OStream(o).os; }" << std::endl;
1563+
myfile << "inline std::wostream& operator<<(std::wostream& os, const " << GetValidFuncName(ClassName) << "& t) { sqlite3pp::ostream_w o(os, t.Delimiter()); return t.OStream(o).os; }" << std::endl;
15481564
}
15491565

15501566
myfile << "\n#endif // !" << HeaderUpper << std::endl;
15511567

15521568
//Done
15531569
myfile.close();
1554-
V_COUT(DETAIL, "Finish creating class '" << ClassName << "' for table '" << TableName << "'");
1570+
V_COUT(DETAIL, "Finish creating class '" << GetValidFuncName(ClassName) << "' for table '" << TableName << "'");
15551571
return true;
15561572
}
15571573
};

0 commit comments

Comments
 (0)