A lightweight, file-based JSON database written in Go that provides simple CRUD operations with thread-safe access and data integrity.
- File-based Storage: Data is stored as JSON files in the filesystem
- Thread-Safe Operations: Concurrent access protection using mutexes
- Simple API: Easy-to-use CRUD operations
- Collection-based Organization: Data organized in collections (similar to tables)
- Atomic Writes: Temporary file writes ensure data integrity
- Logging Support: Built-in logging with configurable levels
Go-Json-Database/
βββ main.go # Example usage and demonstration
βββ db/
β βββ db.go # Core database implementation
βββ types/
β βββ user.go # Data type definitions
βββ users/ # Example data storage directory
β βββ Alice.json
β βββ Bob.json
β βββ ...
βββ go.mod
βββ go.sum
βββ README.md
- Clone the repository:
git clone https://github.com/HakashiKatake/Go-Json-Database.git
cd Go-Json-Database
- Install dependencies:
go mod tidy
- Run the example:
go run main.go
import "github.com/HakashiKatake/Go-Json-Database/db"
// Create a new database instance
database, err := db.New("./data", nil)
if err != nil {
log.Fatal("Error creating database:", err)
}
Store data in a collection with a unique resource identifier.
err := database.Write("users", "john_doe", user.User{
Name: "John Doe",
Age: "30",
Contact: "1234567890",
Company: "Tech Corp",
Address: user.Address{
City: "New York",
State: "NY",
Country: "USA",
Pincode: "10001",
},
})
Retrieve a specific record from a collection.
var userData user.User
err := database.Read("users", "john_doe", &userData)
if err != nil {
log.Println("Error reading user:", err)
}
Retrieve all records from a collection.
records, err := database.ReadAll("users")
if err != nil {
log.Println("Error reading all users:", err)
}
// Parse the JSON records
var allUsers []user.User
for _, record := range records {
var user user.User
if err := json.Unmarshal([]byte(record), &user); err == nil {
allUsers = append(allUsers, user)
}
}
Remove a record from a collection.
err := database.Delete("users", "john_doe")
if err != nil {
log.Println("Error deleting user:", err)
}
type User struct {
Name string `json:"name"`
Age json.Number `json:"age"`
Contact string `json:"contact"`
Company string `json:"company"`
Address Address `json:"address"`
}
type Address struct {
City string `json:"city"`
State string `json:"state"`
Country string `json:"country"`
Pincode json.Number `json:"pincode"`
}
import "github.com/jcelliott/lumber"
options := &db.Options{
Logger: lumber.NewConsoleLogger(lumber.DEBUG),
}
database, err := db.New("./data", options)
lumber.TRACE
lumber.DEBUG
lumber.INFO
lumber.WARN
lumber.ERROR
lumber.FATAL
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/HakashiKatake/Go-Json-Database/db"
user "github.com/HakashiKatake/Go-Json-Database/types"
)
func main() {
// Initialize database
database, err := db.New("./", nil)
if err != nil {
log.Fatal("Error creating database:", err)
}
// Create a user
newUser := user.User{
Name: "Alice Smith",
Age: "28",
Contact: "9876543210",
Company: "Innovation Labs",
Address: user.Address{
City: "San Francisco",
State: "CA",
Country: "USA",
Pincode: "94102",
},
}
// Write user to database
err = database.Write("users", "alice_smith", newUser)
if err != nil {
log.Println("Error writing user:", err)
}
// Read user from database
var retrievedUser user.User
err = database.Read("users", "alice_smith", &retrievedUser)
if err != nil {
log.Println("Error reading user:", err)
} else {
fmt.Printf("Retrieved user: %+v\n", retrievedUser)
}
// Read all users
records, err := database.ReadAll("users")
if err != nil {
log.Println("Error reading all users:", err)
} else {
fmt.Printf("Total records: %d\n", len(records))
}
// Delete user
err = database.Delete("users", "alice_smith")
if err != nil {
log.Println("Error deleting user:", err)
} else {
fmt.Println("User deleted successfully")
}
}
The database implements thread-safe operations using:
- Collection-level mutexes: Each collection has its own mutex
- Atomic writes: Data is written to temporary files first, then renamed
- Concurrent read support: Multiple goroutines can read simultaneously
Data is stored as formatted JSON files:
{
"Name": "John Doe",
"Age": 30,
"Contact": "1234567890",
"Company": "Tech Corp",
"Address": {
"City": "New York",
"State": "NY",
"Country": "USA",
"Pincode": 10001
}
}
The database returns descriptive errors for common scenarios:
- Missing collection or resource names
- File system permission issues
- JSON marshaling/unmarshaling errors
- Non-existent records or collections
- DB's System Structure and Methods

- Methods

- Data integrity

- Driver: Main database engine that handles all operations
- Collections: Logical groupings of related data (like database tables)
- Resources: Individual records within collections
- Mutexes: Thread-safety mechanisms for concurrent access
- Logger: Configurable logging system for debugging and monitoring
Write Operation:
User Data β JSON Marshal β Temporary File β Atomic Rename β Final File
Read Operation:
File Path β File Read β JSON Unmarshal β User Data
Delete Operation:
Resource Path β File/Directory Removal
- Each collection gets its own mutex
- Write operations are fully locked
- Read operations can happen concurrently
- Atomic file operations prevent data corruption
Method | Description | Parameters | Returns |
---|---|---|---|
New() |
Initialize database | dir string, options *Options |
*Driver, error |
Write() |
Store record | collection, resource string, v interface{} |
error |
Read() |
Retrieve record | collection, resource string, v interface{} |
error |
ReadAll() |
Get all records | collection string |
[]string, error |
Delete() |
Remove record | collection, resource string |
error |
Method | Description | Purpose |
---|---|---|
getOrCreateMutex() |
Manage collection mutexes | Thread safety |
stat() |
File existence check | File operations |
- Simple API: Easy to learn and use
- No Dependencies: Minimal external requirements
- File-based: Human-readable storage format
- Thread-safe: Concurrent access support
- Atomic Operations: Data integrity guaranteed
- File I/O Bound: Performance limited by disk speed
- Memory Usage: Entire records loaded into memory
- No Indexing: Linear search for record retrieval
- No Transactions: No multi-operation atomicity
- No Query Language: Basic key-value access only
- Prototyping: Quick database setup for development
- Small Applications: < 10,000 records per collection
- Configuration Storage: Application settings and metadata
- Logging: Structured log data storage
- Testing: Mock database for unit tests
- Use descriptive collection names (e.g., "users", "products", "orders")
- Choose meaningful resource identifiers (e.g., user IDs, product SKUs)
- Validate data before writing to prevent corruption
- Use json.Number for numeric fields to maintain precision
- Implement proper error handling for all operations
- Batch operations when possible to reduce I/O
- Use appropriate data structures for your use case
- Monitor disk space usage regularly
- Consider data archiving for old records
- Implement caching for frequently accessed data
- Validate input data to prevent injection attacks
- Set appropriate file permissions on data directories
- Backup data regularly to prevent data loss
- Monitor access patterns for unusual activity
- Consider encryption for sensitive data
Permission Denied Errors
# Fix file permissions
chmod 755 ./data
chmod 644 ./data/collection/*.json
JSON Marshal/Unmarshal Errors
// Ensure struct fields are exported (capitalized)
type User struct {
Name string `json:"name"` // β
Correct
age string `json:"age"` // β Won't marshal
}
Concurrent Access Issues
// The database handles this automatically
// No additional locking required in user code
import "github.com/jcelliott/lumber"
options := &db.Options{
Logger: lumber.NewConsoleLogger(lumber.DEBUG),
}
database, err := db.New("./data", options)
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
git clone https://github.com/HakashiKatake/Go-Json-Database.git
cd Go-Json-Database
go mod tidy
go test ./...
This project is open source and available under the MIT License.
- lumber - Logging library for Go
- Query language support
- Indexing for faster lookups
- Transaction support
- Data compression
- Backup/restore utilities
- Web interface for data management
- Replication support
- Schema validation
- v1.0.1: Current stable release
- v1.0.0: Initial release with basic CRUD operations
Version: 1.0.1
Go Version: 1.24.2
Maintained by: HakashiKatake