I
I’m currently working on a little project, its a JSON-based database management library. Ive got it all setup pretty neatly, but ive run into an issue where im not able to insert json into the category’s its supposed to go into. Does anyone have similar experience with this?
Heres my db library code:
package db
import (
"encoding/json"
"errors"
"log"
"os"
)
var dbFile = "db.json"
var dbFileCache []map[string]interface{}
// This function is not intended to be used outside this file, hence not included in docs
func DoesFileExist(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
return true, err
}
func LoadCache() {
result, _ := DoesFileExist(dbFile)
if !result {
os.Create(dbFile)
os.WriteFile(dbFile, []byte("[]"), 0644)
}
data, err := os.ReadFile(dbFile)
if err != nil {
log.Fatal(err)
}
if err := json.Unmarshal(data, &dbFileCache); err != nil {
log.Fatal(err)
}
}
func SaveCache() {
newData, err := json.Marshal(dbFileCache)
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile(dbFile, newData, 0644); err != nil {
log.Fatal(err)
}
}
func AddToCache(key string, value map[string]interface{}) {
for i := range dbFileCache {
if _, ok := dbFileCache[i][key]; ok {
dbFileCache[i][key] = append(dbFileCache, value)
break
}
}
}
func SearchCache[T any](key string, field string, search T) []map[string]interface{} {
var foundData []map[string]interface{}
for _, allData := range dbFileCache {
if data, ok := allData[key].(map[string]interface{}); ok {
switch v := any(search).(type) {
case int:
if data[field] == v {
foundData = append(foundData, data)
break
}
case string:
if data[field] == v {
foundData = append(foundData, data)
break
}
}
}
}
return foundData
}
func DeleteFromCache[T any](key string, field string, search T) {
var searchIndex int
for i, allData := range dbFileCache {
if data, ok := allData[key].(map[string]interface{}); ok {
if data[field] == any(search) {
searchIndex = i
break
}
}
}
if searchIndex > 0 {
dbFileCache = append(dbFileCache[:searchIndex], dbFileCache[searchIndex+1:]...)
}
}
How I’m using it:
package main
import (
"db-beta/db"
"log"
"github.com/google/uuid"
)
var userKey = "Users"
var addressKey = "Addresses"
func main() {
db.LoadCache() // Loading the users.json files contents into memory and creating a users.json file if none exists
defer db.SaveCache() // Ensuring that the program saves the user cache to the json file on shutdown
// Important: The two functions above are CRUCIAL for this package to function!
userId := uuid.New().String()
newUser := CreateUser(userId, "emma_davis2", "password2", "[email protected]")
newAddress := CreateAddress(userId, "123 Main St", "New York", "NY", "10001")
// Inserting a new user
db.AddToCache(userKey, newUser)
log.Println("Added user:", newUser)
// Inserting a new address
db.AddToCache(addressKey, newAddress)
log.Println("Added address:", newAddress)
userIdToDelete := "c4a2fef9-0dda-4795-abb2-d67e715a9241" // Important: Replace this with an UserId from db.json to test
user := db.SearchCache(userKey, "UserId", userIdToDelete)
if user != nil {
log.Println("User found:", user)
log.Println("Deleting user with ID:", userIdToDelete)
db.DeleteFromCache(userKey, "UserId", userIdToDelete)
} else {
log.Println("User with ID", userIdToDelete, "does not exist.")
}
addressIdToDelete := "9a4a4582-2af0-465f-bded-ea32c4c30d61" // Important: Replace this with an UserId from db.json to test
address := db.SearchCache(addressKey, "UserId", addressIdToDelete)
if address != nil {
log.Println("Address found:", address)
log.Println("Deleting address with UserID:", addressIdToDelete)
db.DeleteFromCache(addressKey, "UserId", addressIdToDelete)
} else {
log.Println("Address with UserID", addressIdToDelete, "does not exist.")
}
}
func CreateUser(userId, username, password, email string) map[string]interface{} {
return map[string]interface{}{
"UserId": userId,
"Username": username,
"Email": email,
"Password": password,
}
}
func CreateAddress(userId, street, city, state, zip string) map[string]interface{} {
return map[string]interface{}{
"UserId": userId,
"Street": "123 Main St",
"City": "New York",
"State": "NY",
"ZipCode": "10001",
}
}
JSON output:
[
{
"Users": [
{
"Email": "[email protected]",
"Password": "password2",
"UserId": "6b055dd7-9fad-4977-ad72-160324db279c",
"Username": "emma_davis2"
}
]
},
{
"Addresses": [
{
"City": "New York",
"State": "NY",
"Street": "123 Main St",
"UserId": "6b055dd7-9fad-4977-ad72-160324db279c",
"ZipCode": "10001"
}
]
}
]
- The current goal is to make it append inside the “categorys” btw
New contributor
timmy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.