Skip to content

Commit fa0c534

Browse files
committed
Merge branch 'feature/add-indexes-to-json'
2 parents f45a5e3 + 5b4c09f commit fa0c534

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed

demo/database.gd

+28
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,31 @@ func example_of_basic_database_querying():
144144
db.query("PRAGMA encoding;")
145145
cprint("Current database encoding is: {0}".format([db.query_result[0]["encoding"]]))
146146

147+
# Create a TRIGGER and trigger it!
148+
db.query("CREATE TRIGGER increase_salary_after_employee_termination AFTER DELETE ON " + table_name + " BEGIN UPDATE " + table_name + " SET salary = salary + 100;END;")
149+
150+
db.select_rows(table_name, "", ["name", "salary"])
151+
cprint("employees: {0}".format([str(db.query_result_by_reference)]))
152+
153+
cprint("Firing that slacker Paul!")
154+
db.delete_rows(table_name, "name = 'Paul'")
155+
156+
db.select_rows(table_name, "", ["name", "salary"])
157+
cprint("employees: {0}".format([str(db.query_result_by_reference)]))
158+
159+
# Create a VIEW and use it!
160+
db.query("CREATE VIEW cheapest_employee AS SELECT id, name FROM " + table_name + " WHERE salary = (SELECT MIN(salary) FROM company) LIMIT 1;")
161+
162+
# Fire the cheapest employee!
163+
cprint("Firing the cheapest employee!")
164+
db.delete_rows(table_name, "id = (SELECT id FROM cheapest_employee)")
165+
166+
db.select_rows(table_name, "", ["name", "salary"])
167+
cprint("employees: {0}".format([str(db.query_result_by_reference)]))
168+
169+
# Create an INDEX!
170+
db.query("CREATE INDEX idx_name ON " + table_name + "(name);")
171+
147172
# Export the table to a json-file with a specified name
148173
db.export_to_json(json_name + "_new")
149174

@@ -169,6 +194,9 @@ func example_of_basic_database_querying():
169194
cprint("Overwriting database content again with latest backup...")
170195
db.import_from_json(json_name + "_new")
171196

197+
db.query("SELECT * FROM sqlite_master;")
198+
cprint(str(db.query_result_by_reference))
199+
172200
# Try to delete a non-existant table from the database.
173201
if not db.delete_rows(other_table_name, "*"):
174202
cprint("SQL error: " + db.error_message)

src/gdsqlite.cpp

+27-10
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ bool SQLite::import_from_json(String import_path) {
816816
/* Open the json-file and stream its content into a stringstream */
817817
std::ifstream ifs(char_path);
818818
if (ifs.fail()) {
819-
UtilityFunctions::printerr("GDSQLite Error: Failed to open specified json-file (" + import_path + ")");
819+
UtilityFunctions::printerr("GDSQLite Error: " + String(std::strerror(errno)) + " (" + import_path + ")");
820820
return false;
821821
}
822822
std::stringstream buffer;
@@ -849,19 +849,32 @@ bool SQLite::import_from_json(String import_path) {
849849
}
850850
}
851851

852+
/* Find all views that are present in this database */
853+
query(String("SELECT name FROM sqlite_master WHERE type = 'view';"));
854+
TypedArray<Dictionary> old_view_array = query_result.duplicate(true);
855+
int64_t old_number_of_views = old_view_array.size();
856+
/* Drop all old views present in the database */
857+
for (int64_t i = 0; i <= old_number_of_views - 1; i++) {
858+
Dictionary view_dict = old_view_array[i];
859+
String view_name = view_dict["name"];
860+
String query_string = "DROP VIEW " + view_name + ";";
861+
862+
query(query_string);
863+
}
864+
852865
/* Find all tables that are present in this database */
853-
/* We don't care about triggers here since they get dropped automatically when their table is dropped */
866+
/* We don't care about indexes or triggers here since they get dropped automatically when their table is dropped */
854867
query(String("SELECT name FROM sqlite_master WHERE type = 'table';"));
855-
TypedArray<Dictionary> old_database_array = query_result.duplicate(true);
868+
TypedArray<Dictionary> old_table_array = query_result.duplicate(true);
856869
#ifdef SQLITE_ENABLE_FTS5
857870
/* FTS5 creates a bunch of shadow tables that cannot be dropped manually! */
858871
/* The virtual table is responsible for dropping these tables itself */
859-
remove_shadow_tables(old_database_array);
872+
remove_shadow_tables(old_table_array);
860873
#endif
861-
int64_t old_number_of_tables = old_database_array.size();
874+
int64_t old_number_of_tables = old_table_array.size();
862875
/* Drop all old tables present in the database */
863876
for (int64_t i = 0; i <= old_number_of_tables - 1; i++) {
864-
Dictionary table_dict = old_database_array[i];
877+
Dictionary table_dict = old_table_array[i];
865878
String table_name = table_dict["name"];
866879

867880
drop_table(table_name);
@@ -883,7 +896,7 @@ bool SQLite::import_from_json(String import_path) {
883896

884897
for (auto object : objects_to_import) {
885898
if (object.type != TABLE) {
886-
/* The object is a trigger and doesn't have any rows! */
899+
/* The object is an index, view or trigger and doesn't have any rows! */
887900
continue;
888901
}
889902

@@ -923,7 +936,7 @@ bool SQLite::import_from_json(String import_path) {
923936

924937
bool SQLite::export_to_json(String export_path) {
925938
/* Get all names and sql templates for all tables present in the database */
926-
query(String("SELECT name,sql,type FROM sqlite_master WHERE type = 'table' OR type = 'trigger';"));
939+
query(String("SELECT name,sql,type FROM sqlite_master;"));
927940
TypedArray<Dictionary> database_array = query_result.duplicate(true);
928941
#ifdef SQLITE_ENABLE_FTS5
929942
/* FTS5 creates a bunch of shadow tables that should NOT be exported! */
@@ -989,7 +1002,7 @@ bool SQLite::export_to_json(String export_path) {
9891002

9901003
std::ofstream ofs(char_path, std::ios::trunc);
9911004
if (ofs.fail()) {
992-
UtilityFunctions::printerr("GDSQLite Error: Can't open specified json-file, file does not exist or is locked");
1005+
UtilityFunctions::printerr("GDSQLite Error: " + String(std::strerror(errno)) + " (" + export_path + ")");
9931006
return false;
9941007
}
9951008
Ref<JSON> json;
@@ -1047,11 +1060,15 @@ bool SQLite::validate_json(const Array &database_array, std::vector<object_struc
10471060
return false;
10481061
}
10491062
new_object.row_array = temp_dict["row_array"];
1063+
} else if (temp_dict["type"] == String("index")) {
1064+
new_object.type = INDEX;
1065+
} else if (temp_dict["type"] == String("view")) {
1066+
new_object.type = TRIGGER;
10501067
} else if (temp_dict["type"] == String("trigger")) {
10511068
new_object.type = TRIGGER;
10521069
} else {
10531070
/* Did not find the necessary key! */
1054-
UtilityFunctions::printerr("GDSQlite Error: The value of key \"type\" is restricted to either \"table\" or \"trigger\"");
1071+
UtilityFunctions::printerr("GDSQlite Error: The value of key \"type\" is restricted to \"table\", \"index\", \"view\" or \"trigger\"");
10551072
return false;
10561073
}
10571074

src/gdsqlite.h

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
namespace godot {
2323
enum OBJECT_TYPE {
2424
TABLE,
25+
INDEX,
26+
VIEW,
2527
TRIGGER
2628
};
2729
struct object_struct {

0 commit comments

Comments
 (0)