aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-06-27 13:16:27 -0700
committerrtk0c <[email protected]>2022-06-27 13:16:27 -0700
commit8a244363c9171946aa6e4552ce0dcfc8edf761cb (patch)
treeb02b9fb22c80ab0964a22975e636312e1e8f8775 /source
parent8e1724024000701e9a8e2dd0b91e218c1d7a3bdf (diff)
Changeset: 77 Add ability to store structs base classes & properties into database. Methods incomplete.
Diffstat (limited to 'source')
-rw-r--r--source/20-codegen-compiler/CodegenModel.cpp169
1 files changed, 148 insertions, 21 deletions
diff --git a/source/20-codegen-compiler/CodegenModel.cpp b/source/20-codegen-compiler/CodegenModel.cpp
index 4a9a8f8..97a53b8 100644
--- a/source/20-codegen-compiler/CodegenModel.cpp
+++ b/source/20-codegen-compiler/CodegenModel.cpp
@@ -100,8 +100,13 @@ public:
/* Component Statements, initalized on demand */
SQLiteStatement findNamespaceStmt;
SQLiteStatement findOrStoreNamespaceStmt;
+ SQLiteStatement storeStructStmt;
+ SQLiteStatement storeStructBaseClassStmt;
+ SQLiteStatement storeStructPropertyStmt;
+ // TODO store method
SQLiteStatement storeEnumStmt;
SQLiteStatement storeEnumElmStmt;
+ SQLiteStatement deleteFunctionDeclByFilenameStmt;
SQLiteStatement deleteStructDeclByFilenameStmt;
SQLiteStatement deleteEnumDeclByFilenameStmt;
@@ -112,6 +117,7 @@ public:
PrintErrMsgIfPresent(errMsg);
assert(result == SQLITE_OK);
+ // TODO unique with overloading, and container structs
result = sqlite3_exec(database, R"""(
BEGIN TRANSACTION;
CREATE TABLE Namespaces(
@@ -122,13 +128,57 @@ CREATE TABLE Namespaces(
UNIQUE (ParentNamespaceId, Name)
);
+CREATE TABLE DeclFunctions(
+ Id INTEGER PRIMARY KEY,
+ NamespaceId INTEGER REFERENCES Namespaces(Id),
+ Name TEXT,
+ FileName TEXT
+);
+CREATE TABLE DeclFunctionParameters(
+ FunctionId INTEGER REFERENCES DeclFunctions(Id) ON DELETE CASCADE,
+ Name TEXT,
+ Type TEXT,
+ UNIQUE (FunctionId, Name)
+);
+
CREATE TABLE DeclStructs(
Id INTEGER PRIMARY KEY,
NamespaceId INTEGER REFERENCES Namespaces(Id),
- ParentStructId INTEGER REFERENCES DeclStructs(Id),
Name TEXT,
FileName TEXT,
- UNIQUE (NamespaceId, Name)
+ IsMetadataMarked INTEGER
+);
+CREATE TABLE DeclStructBaseClassRelations(
+ StructId INTEGER REFERENCES DeclStructs(Id) ON DELETE CASCADE,
+ -- NOTE: intentionally not foreign keys, because we want relations to still exist even if the base class is deleted
+ -- we do validation after a complete regeneration pass, on reads
+ ParentStructNamespaceId INTEGER,
+ ParentStructName TEXT,
+ UNIQUE (StructId, ParentStructNamespaceId, ParentStructName)
+);
+CREATE TABLE DeclStructProperties(
+ StructId INTEGER REFERENCES DeclStructs(Id) ON DELETE CASCADE,
+ Name TEXT,
+ Type TEXT,
+ -- NOTE: getter and setter may or may not be methods; search the DeclStructMethods table if needed
+ GetterName TEXT,
+ SetterName TEXT,
+ IsPlainField INTEGER GENERATED ALWAYS AS (GetterName = '' AND SetterName = '') VIRTUAL,
+ IsMetadataMarked INTEGER
+);
+CREATE TABLE DeclStructMethods(
+ Id INTEGER PRIMARY KEY,
+ StructId INTEGER REFERENCES DeclStructs(Id) ON DELETE CASCADE,
+ Name TEXT,
+ Type TEXT,
+ IsConst INTEGER,
+ IsMetadataMarked INTEGER
+);
+CREATE TABLE DeclStructMethodParameters(
+ MethodId INTEGER REFERENCES DeclStructMethods(Id) ON DELETE CASCADE,
+ Name TEXT,
+ Type TEXT,
+ UNIQUE (MethodId, Name)
);
CREATE TABLE DeclEnums(
@@ -136,8 +186,7 @@ CREATE TABLE DeclEnums(
NamespaceId INTEGER REFERENCES Namespaces(Id),
Name TEXT,
UnderlyingType TEXT,
- FileName TEXT,
- UNIQUE (NamespaceId, Name)
+ FileName TEXT
);
CREATE TABLE DeclEnumElements(
EnumId INTEGER REFERENCES DeclEnums(Id) ON DELETE CASCADE,
@@ -146,10 +195,17 @@ CREATE TABLE DeclEnumElements(
UNIQUE (EnumId, Name)
);
-CREATE INDEX Index_DeclStructs_FileName
- ON DeclStructs(FileName);
-CREATE INDEX Index_DeclEnums_FileName
- ON DeclEnums(FileName);
+CREATE INDEX Index_DeclFunctions_FileName ON DeclFunctions(FileName);
+CREATE INDEX Index_DeclStructs_FileName ON DeclStructs(FileName);
+CREATE INDEX Index_DeclEnums_FileName ON DeclEnums(FileName);
+
+CREATE UNIQUE INDEX Index_DeclFunctions_Identity ON DeclFunctions(NamespaceId, Name);
+
+CREATE UNIQUE INDEX Index_DeclStruct_Identity ON DeclStructs(NamespaceId, Name);
+CREATE UNIQUE INDEX Index_DeclStructProperties_Identity ON DeclStructProperties(StructId, Name);
+CREATE UNIQUE INDEX Index_DeclStructMethods_Identity ON DeclStructMethods(StructId, Name);
+
+CREATE UNIQUE INDEX Index_DeclEnums_Identity ON DeclEnums(NamespaceId, Name);
INSERT INTO Namespaces(Id, ParentNamespaceId, Name)
VALUES
@@ -363,6 +419,13 @@ CodegenModelArchive::CodegenModelArchive(std::string_view dbPath)
throw std::runtime_error(msg);
}
+ // NOTE: These pragmas are not persistent, so we need to set them every time
+ // As of SQLite3 3.38.5, it defaults to foreign_keys = OFF, so we need this to be on for ON DELETE CASCADE and etc. to work
+ sqlite3_exec(m->database, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);
+ // This database is used for a buildsystem and can be regenerated at any time. We don't care for the slightest about data integrity, we just want fast updates
+ sqlite3_exec(m->database, "PRAGMA synchronous = OFF", nullptr, nullptr, nullptr);
+ sqlite3_exec(m->database, "PRAGMA journal_mode = MEMORY", nullptr, nullptr, nullptr);
+
{
SQLiteStatement readVersionStmt;
readVersionStmt.InitializeLazily(m->database, "PRAGMA user_version"sv);
@@ -385,13 +448,6 @@ CodegenModelArchive::CodegenModelArchive(std::string_view dbPath)
}
}
- // NOTE: These pragmas are not persistent, so we need to set them every time
- // SQLite3 as of 2022-06-24 defaults to foreign_keys = OFF, we need this to be on for ON DELETE CASCADE and etc. to work
- sqlite3_exec(m->database, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);
- // This database is used for a buildsystem and can be regenerated at any time. We don't care for the slightest about data integrity, we just want fast updates
- sqlite3_exec(m->database, "PRAGMA synchronous = OFF", nullptr, nullptr, nullptr);
- sqlite3_exec(m->database, "PRAGMA journal_mode = MEMORY", nullptr, nullptr, nullptr);
-
m->beginTransactionStmt.InitializeLazily(m->database, "BEGIN TRANSACTION");
m->commitTransactionStmt.InitializeLazily(m->database, "COMMIT TRANSACTION");
m->rollbackTransactionStmt.InitializeLazily(m->database, "ROLLBACK TRANSACTION");
@@ -404,11 +460,13 @@ CodegenModelArchive::~CodegenModelArchive() {
void CodegenModelArchive::DeleteDeclsRelatedToFile(std::string_view filename) {
// -Argument- -Description-
// ?1 The filename to delete
+ m->deleteFunctionDeclByFilenameStmt.InitializeLazily(m->database, "DELETE FROM DeclFunctions WHERE FileName = ?1"sv);
m->deleteStructDeclByFilenameStmt.InitializeLazily(m->database, "DELETE FROM DeclStructs WHERE FileName = ?1;"sv);
m->deleteEnumDeclByFilenameStmt.InitializeLazily(m->database, "DELETE FROM DeclEnums WHERE FileName = ?1;"sv);
m->BeginTransaction();
auto stmtList = {
+ m->deleteFunctionDeclByFilenameStmt.stmt,
m->deleteStructDeclByFilenameStmt.stmt,
m->deleteEnumDeclByFilenameStmt.stmt,
};
@@ -454,7 +512,76 @@ void CodegenModelArchive::Store(const CodegenModel& cgInput) {
}
void CodegenModelArchive::StoreStruct(const DeclStruct& decl) {
- // TODO
+ // -Argument- -Description-
+ // ?1 Namespace ID
+ // ?2 Struct name
+ // ?3 File containing the struct
+ m->storeStructStmt.InitializeLazily(m->database, R"""(
+INSERT INTO DeclStructs(NamespaceId, Name, FileName, IsMetadataMarked)
+ VALUES (?1, ?2, ?3, TRUE)
+ ON CONFLICT DO UPDATE SET
+ FileName = ?3
+ RETURNING Id
+)"""sv);
+
+ // -Argument- -Description-
+ // ?1 Struct ID
+ // ?2 Parent struct's namespace ID
+ // ?3 Parent struct's name
+ m->storeStructBaseClassStmt.InitializeLazily(m->database, R"""(
+INSERT INTO DeclStructBaseClassRelations(StructId, ParentStructNamespaceId, ParentStructName)
+ VALUES (?1, ?2, ?3)
+)"""sv);
+
+ // -Argument- -Description-
+ // ?1 Struct ID
+ // ?2 Property name
+ // ?3 Property type
+ // ?4 Getter name (optional)
+ // ?5 Setter name (optional)
+ m->storeStructPropertyStmt.InitializeLazily(m->database, R"""(
+INSERT INTO DeclStructProperties(StructId, Name, Type, GetterName, SetterName, IsMetadataMarked)
+ VALUES (?1, ?2, ?3, ?4, ?5, TRUE)
+)"""sv);
+
+ sqlite3_bind_int64(m->storeStructStmt, 1, m->FindNamespace(decl.container));
+ sqlite3_bind_text(m->storeStructStmt, 2, decl.name.c_str(), decl.name.size(), nullptr);
+ if (decl.sourceFile) {
+ sqlite3_bind_text(m->storeStructStmt, 3, decl.sourceFile->filename.data(), decl.sourceFile->filename.size(), nullptr);
+ } else {
+ sqlite3_bind_text(m->storeStructStmt, 3, "", 0, nullptr);
+ }
+ int result = sqlite3_step(m->storeStructStmt);
+ assert(result == SQLITE_ROW);
+ int64_t structId = sqlite3_column_int64(m->storeStructStmt, 0);
+ sqlite3_reset(m->storeStructStmt);
+ sqlite3_clear_bindings(m->storeStructStmt);
+
+ for (auto& baseClass : decl.baseClasses) {
+ sqlite3_bind_int64(m->storeStructBaseClassStmt, 1, structId);
+ sqlite3_bind_int64(m->storeStructBaseClassStmt, 2, m->FindNamespace(baseClass->container));
+ sqlite3_bind_text(m->storeStructBaseClassStmt, 3, baseClass->name.c_str(), baseClass->name.size(), nullptr);
+ int result = sqlite3_step(m->storeStructBaseClassStmt);
+ assert(result == SQLITE_DONE);
+ sqlite3_reset(m->storeStructBaseClassStmt);
+ sqlite3_clear_bindings(m->storeStructBaseClassStmt);
+ }
+
+ for (auto& property : decl.memberVariables) {
+ sqlite3_bind_int64(m->storeStructPropertyStmt, 1, structId);
+ sqlite3_bind_text(m->storeStructPropertyStmt, 2, property.name.c_str(), property.name.size(), nullptr);
+ sqlite3_bind_text(m->storeStructPropertyStmt, 3, property.type.c_str(), property.type.size(), nullptr);
+ sqlite3_bind_text(m->storeStructPropertyStmt, 4, property.getterName.c_str(), property.getterName.size(), nullptr);
+ sqlite3_bind_text(m->storeStructPropertyStmt, 5, property.setterName.c_str(), property.setterName.size(), nullptr);
+ int result = sqlite3_step(m->storeStructPropertyStmt);
+ assert(result == SQLITE_DONE);
+ sqlite3_reset(m->storeStructPropertyStmt);
+ sqlite3_clear_bindings(m->storeStructPropertyStmt);
+ }
+
+ for (auto& method : decl.memberFunctions) {
+ // TODO
+ }
}
void CodegenModelArchive::StoreFunction(const DeclFunction& decl) {
@@ -473,7 +600,7 @@ INSERT INTO DeclEnums(NamespaceId, Name, UnderlyingType, FileName)
ON CONFLICT DO UPDATE SET
UnderlyingType = ?3,
FileName = ?4
- RETURNING Id;
+ RETURNING Id
)"""sv);
// -Argument- -Description-
@@ -483,7 +610,7 @@ INSERT INTO DeclEnums(NamespaceId, Name, UnderlyingType, FileName)
m->storeEnumElmStmt.InitializeLazily(m->database, R"""(
INSERT INTO DeclEnumElements(EnumId, Name, Value)
VALUES (?1, ?2, ?3)
- ON CONFLICT DO UPDATE SET Value=?3;
+ ON CONFLICT DO UPDATE SET Value=?3
)"""sv);
sqlite3_bind_int(m->storeEnumStmt, 1, m->FindNamespace(decl.container));
@@ -492,16 +619,16 @@ INSERT INTO DeclEnumElements(EnumId, Name, Value)
if (decl.sourceFile) {
sqlite3_bind_text(m->storeEnumStmt, 4, decl.sourceFile->filename.data(), decl.sourceFile->filename.size(), nullptr);
} else {
- sqlite3_bind_text(m->storeEnumElmStmt, 4, "", 0, nullptr);
+ sqlite3_bind_text(m->storeEnumStmt, 4, "", 0, nullptr);
}
int result = sqlite3_step(m->storeEnumStmt);
assert(result == SQLITE_ROW);
- auto EnumId = sqlite3_column_int64(m->storeEnumStmt, 0);
+ auto enumId = sqlite3_column_int64(m->storeEnumStmt, 0);
sqlite3_reset(m->storeEnumStmt);
sqlite3_clear_bindings(m->storeEnumStmt);
for (auto& elm : decl.elements) {
- sqlite3_bind_int64(m->storeEnumElmStmt, 1, EnumId);
+ sqlite3_bind_int64(m->storeEnumElmStmt, 1, enumId);
sqlite3_bind_text(m->storeEnumElmStmt, 2, elm.name.c_str(), elm.name.size(), nullptr);
sqlite3_bind_int64(m->storeEnumElmStmt, 3, elm.value);
int result = sqlite3_step(m->storeEnumElmStmt);