mirror of
https://github.com/sbrow/envr.git
synced 2026-06-27 18:48:33 -04:00
chore: Cleaned up code.
This commit is contained in:
145
db.odin
145
db.odin
@@ -27,6 +27,7 @@ SyncDirection :: enum {
|
||||
}
|
||||
|
||||
Db :: struct {
|
||||
// Pointer to the sqlite db
|
||||
db: ^rawptr,
|
||||
cfg: Config,
|
||||
changed: bool,
|
||||
@@ -64,8 +65,8 @@ db_open :: proc(cfg_path: string) -> (Db, bool) {
|
||||
return Db{}, false
|
||||
}
|
||||
|
||||
create_sql := "CREATE TABLE IF NOT EXISTS envr_env_files (path TEXT PRIMARY KEY NOT NULL, remotes TEXT, sha256 TEXT NOT NULL, contents TEXT NOT NULL)"
|
||||
rc = sqlite.db_exec(db, string_to_cstring(create_sql), nil, nil, nil)
|
||||
create_sql: cstring = "CREATE TABLE IF NOT EXISTS envr_env_files (path TEXT PRIMARY KEY NOT NULL, remotes TEXT, sha256 TEXT NOT NULL, contents TEXT NOT NULL)"
|
||||
rc = sqlite.db_exec(db, create_sql, nil, nil, nil)
|
||||
if rc != sqlite.OK {
|
||||
fmt.printf("Error creating table: %s\n", sqlite.db_errmsg(db))
|
||||
sqlite.db_close(db)
|
||||
@@ -125,10 +126,15 @@ db_close :: proc(d: ^Db) {
|
||||
sqlite.db_close(d.db)
|
||||
}
|
||||
|
||||
db_list :: proc(d: ^Db) -> (results: [dynamic]EnvFile, ok: bool) {
|
||||
sql := "SELECT path, remotes, sha256, contents FROM envr_env_files"
|
||||
db_list :: proc(d: ^Db, allocator := context.allocator) -> (results: [dynamic]EnvFile, ok: bool) {
|
||||
stmt: ^rawptr
|
||||
rc := sqlite.prepare_v2(d.db, string_to_cstring(sql), -1, &stmt, nil)
|
||||
rc := sqlite.prepare_v2(
|
||||
d.db,
|
||||
"SELECT path, remotes, sha256, contents FROM envr_env_files",
|
||||
-1,
|
||||
&stmt,
|
||||
nil,
|
||||
)
|
||||
if rc != sqlite.OK {
|
||||
fmt.printf("Error preparing query: %s\n", sqlite.db_errmsg(d.db))
|
||||
return
|
||||
@@ -145,15 +151,12 @@ db_list :: proc(d: ^Db) -> (results: [dynamic]EnvFile, ok: bool) {
|
||||
return
|
||||
}
|
||||
|
||||
path := cstring_to_string(sqlite.column_text(stmt, 0))
|
||||
remotes_json := cstring_to_string(sqlite.column_text(stmt, 1))
|
||||
sha := cstring_to_string(sqlite.column_text(stmt, 2))
|
||||
contents := cstring_to_string(sqlite.column_text(stmt, 3))
|
||||
|
||||
remotes: [dynamic]string
|
||||
remotes_json := string(sqlite.column_text(stmt, 1))
|
||||
remotes := make([dynamic]string, strings.count(remotes_json, ",") + 1, allocator)
|
||||
if len(remotes_json) > 0 {
|
||||
json.unmarshal_string(remotes_json, &remotes)
|
||||
}
|
||||
path := clone_cstring(sqlite.column_text(stmt, 0), allocator)
|
||||
|
||||
append(
|
||||
&results,
|
||||
@@ -161,8 +164,8 @@ db_list :: proc(d: ^Db) -> (results: [dynamic]EnvFile, ok: bool) {
|
||||
Path = path,
|
||||
Dir = filepath.dir(path),
|
||||
Remotes = remotes,
|
||||
Sha256 = sha,
|
||||
contents = contents,
|
||||
Sha256 = clone_cstring(sqlite.column_text(stmt, 2), allocator),
|
||||
contents = clone_cstring(sqlite.column_text(stmt, 3), allocator),
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -176,8 +179,7 @@ db_vacuum_to_file :: proc(db: ^rawptr, path: string) -> bool {
|
||||
b: strings.Builder
|
||||
strings.builder_init(&b)
|
||||
fmt.sbprintf(&b, "VACUUM INTO '%s'", path)
|
||||
sql := strings.to_string(b)
|
||||
rc := sqlite.db_exec(db, string_to_cstring(sql), nil, nil, nil)
|
||||
rc := sqlite.db_exec(db, to_cstring(&b), nil, nil, nil)
|
||||
if rc != sqlite.OK {
|
||||
fmt.printf("Error vacuuming database: %s\n", sqlite.db_errmsg(db))
|
||||
return false
|
||||
@@ -221,7 +223,7 @@ db_attach_and_copy :: proc(mem_db: ^rawptr, src_path: string) -> bool {
|
||||
fmt.sbprintf(&b, "ATTACH DATABASE '%s' AS source", src_path)
|
||||
attach_sql := strings.to_string(b)
|
||||
|
||||
rc := sqlite.db_exec(mem_db, string_to_cstring(attach_sql), nil, nil, nil)
|
||||
rc := sqlite.db_exec(mem_db, to_cstring(attach_sql), nil, nil, nil)
|
||||
if rc != sqlite.OK {
|
||||
fmt.printf("Error attaching database: %s\n", sqlite.db_errmsg(mem_db))
|
||||
return false
|
||||
@@ -284,8 +286,7 @@ get_git_remotes :: proc(dir: string) -> [dynamic]string {
|
||||
return remotes
|
||||
}
|
||||
|
||||
output_str := string(data)
|
||||
lines := strings.split(output_str, "\n")
|
||||
lines := strings.split(string(data), "\n")
|
||||
|
||||
for &line in lines {
|
||||
line = strings.trim_space(line)
|
||||
@@ -312,7 +313,10 @@ new_env_file :: proc(path: string) -> (EnvFile, bool) {
|
||||
fmt.printf("Error getting absolute path: %v\n", abs_err)
|
||||
return EnvFile{}, false
|
||||
}
|
||||
cloned_path, _ := strings.clone(abs_path)
|
||||
cloned_path, err := strings.clone(abs_path)
|
||||
if err != nil {
|
||||
panic("Ran out of memory")
|
||||
}
|
||||
|
||||
dir := filepath.dir(cloned_path)
|
||||
|
||||
@@ -325,14 +329,14 @@ new_env_file :: proc(path: string) -> (EnvFile, bool) {
|
||||
}
|
||||
|
||||
digest := hash.hash_bytes(hash.Algorithm.SHA256, data)
|
||||
// TODO: Handle error
|
||||
hex_bytes, _ := hex.encode(digest)
|
||||
sha_str := string(hex_bytes)
|
||||
|
||||
return EnvFile {
|
||||
Path = cloned_path,
|
||||
Dir = dir,
|
||||
Remotes = remotes,
|
||||
Sha256 = sha_str,
|
||||
Sha256 = string(hex_bytes),
|
||||
contents = string(data),
|
||||
},
|
||||
true
|
||||
@@ -345,19 +349,33 @@ db_insert :: proc(d: ^Db, file: EnvFile) -> bool {
|
||||
return false
|
||||
}
|
||||
|
||||
sql := "INSERT OR REPLACE INTO envr_env_files (path, remotes, sha256, contents) VALUES (?, ?, ?, ?)"
|
||||
sql: cstring =
|
||||
"INSERT OR REPLACE INTO " +
|
||||
"envr_env_files (path, remotes, sha256, contents) VALUES (?, ?, ?, ?)"
|
||||
stmt: ^rawptr
|
||||
rc := sqlite.prepare_v2(d.db, string_to_cstring(sql), -1, &stmt, nil)
|
||||
rc := sqlite.prepare_v2(d.db, sql, -1, &stmt, nil)
|
||||
if rc != sqlite.OK {
|
||||
fmt.printf("Error preparing insert: %s\n", sqlite.db_errmsg(d.db))
|
||||
return false
|
||||
}
|
||||
defer sqlite.finalize(stmt)
|
||||
|
||||
rc = sqlite.bind_text(stmt, 1, string_to_cstring(file.Path), -1, nil)
|
||||
rc = sqlite.bind_text(stmt, 2, string_to_cstring(string(remotes_json)), -1, nil)
|
||||
rc = sqlite.bind_text(stmt, 3, string_to_cstring(file.Sha256), -1, nil)
|
||||
rc = sqlite.bind_text(stmt, 4, string_to_cstring(file.contents), -1, nil)
|
||||
// TODO: deal with elsewhere?
|
||||
cpath := to_cstring(file.Path)
|
||||
defer delete(cpath)
|
||||
rc = sqlite.bind_text(stmt, 1, cpath, -1, nil)
|
||||
|
||||
cremotes := to_cstring(string(remotes_json))
|
||||
defer delete(cremotes)
|
||||
rc = sqlite.bind_text(stmt, 2, cremotes, -1, nil)
|
||||
|
||||
csha := to_cstring(file.Sha256)
|
||||
defer delete(csha)
|
||||
rc = sqlite.bind_text(stmt, 3, csha, -1, nil)
|
||||
|
||||
ccontents := to_cstring(file.contents)
|
||||
defer delete(ccontents)
|
||||
rc = sqlite.bind_text(stmt, 4, ccontents, -1, nil)
|
||||
|
||||
rc = sqlite.step(stmt)
|
||||
if rc != sqlite.DONE {
|
||||
@@ -369,17 +387,19 @@ db_insert :: proc(d: ^Db, file: EnvFile) -> bool {
|
||||
return true
|
||||
}
|
||||
|
||||
db_fetch :: proc(d: ^Db, path: string) -> (EnvFile, bool) {
|
||||
sql := "SELECT path, remotes, sha256, contents FROM envr_env_files WHERE path = ?"
|
||||
db_fetch :: proc(d: ^Db, path: string, allocator := context.allocator) -> (EnvFile, bool) {
|
||||
sql: cstring = "SELECT path, remotes, sha256, contents FROM envr_env_files WHERE path = ?"
|
||||
stmt: ^rawptr
|
||||
rc := sqlite.prepare_v2(d.db, string_to_cstring(sql), -1, &stmt, nil)
|
||||
rc := sqlite.prepare_v2(d.db, sql, -1, &stmt, nil)
|
||||
if rc != sqlite.OK {
|
||||
fmt.printf("Error preparing fetch: %s\n", sqlite.db_errmsg(d.db))
|
||||
return EnvFile{}, false
|
||||
}
|
||||
defer sqlite.finalize(stmt)
|
||||
|
||||
rc = sqlite.bind_text(stmt, 1, string_to_cstring(path), -1, nil)
|
||||
cpath := to_cstring(path, allocator)
|
||||
defer delete(cpath, allocator)
|
||||
rc = sqlite.bind_text(stmt, 1, cpath, -1, nil)
|
||||
rc = sqlite.step(stmt)
|
||||
if rc == sqlite.DONE {
|
||||
fmt.printf("No file found with path: %s\n", path)
|
||||
@@ -390,38 +410,37 @@ db_fetch :: proc(d: ^Db, path: string) -> (EnvFile, bool) {
|
||||
return EnvFile{}, false
|
||||
}
|
||||
|
||||
file_path := cstring_to_string(sqlite.column_text(stmt, 0))
|
||||
remotes_json := cstring_to_string(sqlite.column_text(stmt, 1))
|
||||
sha := cstring_to_string(sqlite.column_text(stmt, 2))
|
||||
contents := cstring_to_string(sqlite.column_text(stmt, 3))
|
||||
|
||||
remotes: [dynamic]string
|
||||
remotes_json := string(sqlite.column_text(stmt, 1))
|
||||
remotes := make([dynamic]string, strings.count(remotes_json, ",") + 1, allocator)
|
||||
if len(remotes_json) > 0 {
|
||||
json.unmarshal_string(remotes_json, &remotes)
|
||||
json.unmarshal_string(remotes_json, &remotes, allocator = allocator)
|
||||
}
|
||||
|
||||
cloned_path, _ := strings.clone(file_path)
|
||||
file_path := clone_cstring(sqlite.column_text(stmt, 0))
|
||||
|
||||
return EnvFile {
|
||||
Path = cloned_path,
|
||||
Dir = filepath.dir(cloned_path),
|
||||
Path = file_path,
|
||||
Dir = filepath.dir(file_path),
|
||||
Remotes = remotes,
|
||||
Sha256 = sha,
|
||||
contents = contents,
|
||||
Sha256 = clone_cstring(sqlite.column_text(stmt, 2), allocator),
|
||||
contents = clone_cstring(sqlite.column_text(stmt, 3), allocator),
|
||||
},
|
||||
true
|
||||
}
|
||||
|
||||
db_delete :: proc(d: ^Db, path: string) -> bool {
|
||||
sql := "DELETE FROM envr_env_files WHERE path = ?"
|
||||
sql: cstring = "DELETE FROM envr_env_files WHERE path = ?"
|
||||
stmt: ^rawptr
|
||||
rc := sqlite.prepare_v2(d.db, string_to_cstring(sql), -1, &stmt, nil)
|
||||
rc := sqlite.prepare_v2(d.db, sql, -1, &stmt, nil)
|
||||
if rc != sqlite.OK {
|
||||
fmt.printf("Error preparing delete: %s\n", sqlite.db_errmsg(d.db))
|
||||
return false
|
||||
}
|
||||
defer sqlite.finalize(stmt)
|
||||
|
||||
rc = sqlite.bind_text(stmt, 1, string_to_cstring(path), -1, nil)
|
||||
cpath := to_cstring(path)
|
||||
defer delete(cpath)
|
||||
rc = sqlite.bind_text(stmt, 1, cpath, -1, nil)
|
||||
rc = sqlite.step(stmt)
|
||||
if rc != sqlite.DONE {
|
||||
fmt.printf("Error deleting: %s\n", sqlite.db_errmsg(d.db))
|
||||
@@ -437,19 +456,30 @@ db_delete :: proc(d: ^Db, path: string) -> bool {
|
||||
return true
|
||||
}
|
||||
|
||||
cstring_to_string :: proc(cs: cstring) -> string {
|
||||
if cs == nil {
|
||||
return ""
|
||||
}
|
||||
s, _ := strings.clone_from_cstring(cs)
|
||||
return s
|
||||
to_cstring :: proc {
|
||||
string_to_cstring,
|
||||
strings.to_cstring,
|
||||
}
|
||||
|
||||
string_to_cstring :: proc(s: string) -> cstring {
|
||||
cs, _ := strings.clone_to_cstring(s)
|
||||
string_to_cstring :: proc(s: string, allocator := context.allocator) -> cstring {
|
||||
cs, err := strings.clone_to_cstring(s, allocator)
|
||||
if err != nil {
|
||||
fmt.printf("Failed to convert string to cstring: %v\n", err)
|
||||
panic("Allocation Exception")
|
||||
}
|
||||
return cs
|
||||
}
|
||||
|
||||
clone_cstring :: proc(c: cstring, allocator := context.allocator) -> string {
|
||||
str, err := strings.clone_from_cstring(c, allocator)
|
||||
if err != nil {
|
||||
fmt.printf("Failed to convert string to cstring: %v\n", err)
|
||||
panic("Allocation Exception")
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
db_update_required :: proc(status: SyncFlag) -> bool {
|
||||
return .BackedUp in status || .DirUpdated in status
|
||||
}
|
||||
@@ -505,7 +535,11 @@ env_file_backup :: proc(f: ^EnvFile) -> bool {
|
||||
|
||||
f.contents = string(data)
|
||||
digest := hash.hash_bytes(hash.Algorithm.SHA256, data)
|
||||
hex_bytes, _ := hex.encode(digest)
|
||||
hex_bytes, alloc_err := hex.encode(digest)
|
||||
if alloc_err != nil {
|
||||
fmt.printf("Error generating hash for file %s: %v\n", f.Path, alloc_err)
|
||||
return false
|
||||
}
|
||||
f.Sha256 = string(hex_bytes)
|
||||
return true
|
||||
}
|
||||
@@ -555,6 +589,7 @@ env_file_sync :: proc(f: ^EnvFile, dir: SyncDirection, d: ^Db) -> (SyncFlag, str
|
||||
}
|
||||
|
||||
digest := hash.hash_bytes(hash.Algorithm.SHA256, data)
|
||||
// TODO: Handle error
|
||||
hex_bytes, _ := hex.encode(digest)
|
||||
current_sha := string(hex_bytes)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user