Installation
The Go bindings use CGO to link against a pre-built static library. Your final binary is fully self-contained with no external dependencies.
Get the package
go get github.com/sohzm/jasonisnthappy/bindings/go
Download the native library
go generate github.com/sohzm/jasonisnthappy/bindings/go
This downloads the pre-compiled static library (.a file) for your platform from GitHub releases and caches it in lib/<platform>/.
Build your application
CGO statically links the library into your binary. The result is a single standalone executable with zero runtime dependencies.
Benefits:
Single self-contained binary
No external library files needed
Perfect for production deployment
Works in Docker containers, cloud functions, etc.
No Rust compiler needed
Quick start
package main
import (
" fmt "
" log "
db " github.com/sohzm/jasonisnthappy/bindings/go "
)
func main () {
// Open database
database , err := db . Open ( "./my_database.db" )
if err != nil {
log . Fatal ( err )
}
defer database . Close ()
// Begin transaction
tx , err := database . BeginTransaction ()
if err != nil {
log . Fatal ( err )
}
defer tx . Rollback () // Auto-rollback if not committed
// Insert document
doc := map [ string ] interface {}{
"name" : "Alice" ,
"age" : 30 ,
"email" : "alice@example.com" ,
}
id , err := tx . Insert ( "users" , doc )
if err != nil {
log . Fatal ( err )
}
fmt . Printf ( "Inserted document with ID: %s \n " , id )
// Find by ID
var result map [ string ] interface {}
found , err := tx . FindByID ( "users" , id , & result )
if err != nil {
log . Fatal ( err )
}
if found {
fmt . Printf ( "Found: %+v \n " , result )
}
// Update
doc [ "age" ] = 31
err = tx . UpdateByID ( "users" , id , doc )
if err != nil {
log . Fatal ( err )
}
// Find all
var all [] map [ string ] interface {}
err = tx . FindAll ( "users" , & all )
if err != nil {
log . Fatal ( err )
}
fmt . Printf ( "All users: %+v \n " , all )
// Commit transaction
err = tx . Commit ()
if err != nil {
log . Fatal ( err )
}
}
API reference
Database
Opening databases
// Open a database at the specified path
func Open ( path string ) ( * Database , error )
// Open with custom options
func OpenWithOptions ( path string , opts DatabaseOptions ) ( * Database , error )
// Get default options
func DefaultDatabaseOptions () DatabaseOptions
db , err := jasonisnthappy . Open ( "./my_database.db" )
if err != nil {
log . Fatal ( err )
}
defer db . Close ()
Configuration
type DatabaseOptions struct {
CacheSize uint
AutoCheckpointThreshold uint64
FilePermissions uint32
ReadOnly bool
MaxBulkOperations uint
MaxDocumentSize uint
MaxRequestBodySize uint
}
type TransactionConfig struct {
MaxRetries uint
RetryBackoffBaseMs uint64
MaxRetryBackoffMs uint64
}
// Set transaction retry configuration
func ( d * Database ) SetTransactionConfig ( config TransactionConfig ) error
// Get current configuration
func ( d * Database ) GetTransactionConfig () ( * TransactionConfig , error )
// Set auto-checkpoint threshold
func ( d * Database ) SetAutoCheckpointThreshold ( threshold uint64 ) error
Database info
// Get database file path
func ( d * Database ) GetPath () ( string , error )
// Check if read-only
func ( d * Database ) IsReadOnly () ( bool , error )
// Get limits
func ( d * Database ) MaxBulkOperations () ( uint , error )
func ( d * Database ) MaxDocumentSize () ( uint , error )
func ( d * Database ) MaxRequestBodySize () ( uint , error )
// List all collections
func ( d * Database ) ListCollections () ([] string , error )
// Get collection statistics
func ( d * Database ) CollectionStats ( collectionName string ) ( map [ string ] interface {}, error )
// Get comprehensive database info
func ( d * Database ) DatabaseInfo () ( map [ string ] interface {}, error )
Transaction
Creating transactions
// Start a new transaction
func ( d * Database ) BeginTransaction () ( * Transaction , error )
// Run transaction with automatic retries
func ( d * Database ) RunTransaction ( fn func ( * Transaction ) error ) error
Manual transaction
Auto-retry transaction
tx , err := db . BeginTransaction ()
if err != nil {
return err
}
defer tx . Rollback () // Safety net
id , err := tx . Insert ( "users" , doc )
if err != nil {
return err
}
return tx . Commit ()
err := db . RunTransaction ( func ( tx * jasonisnthappy . Transaction ) error {
id , err := tx . Insert ( "users" , doc )
if err != nil {
return err
}
// Transaction will auto-commit if no error
return nil
})
CRUD operations
// Insert a document into a collection
func ( t * Transaction ) Insert ( collectionName string , doc interface {}) ( string , error )
// Find document by ID
func ( t * Transaction ) FindByID ( collectionName , id string , result interface {}) ( bool , error )
// Update document by ID
func ( t * Transaction ) UpdateByID ( collectionName , id string , doc interface {}) error
// Delete document by ID
func ( t * Transaction ) DeleteByID ( collectionName , id string ) error
// Find all documents in a collection
func ( t * Transaction ) FindAll ( collectionName string , result interface {}) error
// Count documents
func ( t * Transaction ) Count ( collectionName string ) ( int64 , error )
Transaction control
// Commit the transaction
func ( t * Transaction ) Commit () error
// Rollback the transaction (safe to call multiple times)
func ( t * Transaction ) Rollback ()
// Check if transaction is still active
func ( t * Transaction ) IsActive () bool
Always defer tx.Rollback() after creating a transaction. It’s safe to call even after a successful commit.
Collection management
// Create a new collection
func ( t * Transaction ) CreateCollection ( name string ) error
// Drop a collection
func ( t * Transaction ) DropCollection ( name string ) error
// Rename a collection
func ( t * Transaction ) RenameCollection ( oldName , newName string ) error
Collection
For non-transactional operations with auto-commit:
// Get a collection handle
func ( d * Database ) GetCollection ( name string ) ( * Collection , error )
// Free the collection handle
func ( c * Collection ) Free ()
// Get collection name
func ( c * Collection ) Name () ( string , error )
Basic CRUD
// Insert a document
func ( c * Collection ) Insert ( doc interface {}) ( string , error )
// Find by ID
func ( c * Collection ) FindByID ( id string , result interface {}) ( bool , error )
// Update by ID
func ( c * Collection ) UpdateByID ( id string , updates interface {}) error
// Delete by ID
func ( c * Collection ) DeleteByID ( id string ) error
// Find all documents
func ( c * Collection ) FindAll ( result interface {}) error
// Count all documents
func ( c * Collection ) Count () ( int64 , error )
Querying
// Find documents matching a filter
func ( c * Collection ) Find ( filter string , result interface {}) error
// Find first document matching a filter
func ( c * Collection ) FindOne ( filter string , result interface {}) ( bool , error )
// Update all documents matching a filter
func ( c * Collection ) Update ( filter string , update interface {}) ( int64 , error )
// Update first document matching a filter
func ( c * Collection ) UpdateOne ( filter string , update interface {}) ( bool , error )
// Delete all documents matching a filter
func ( c * Collection ) Delete ( filter string ) ( int64 , error )
// Delete first document matching a filter
func ( c * Collection ) DeleteOne ( filter string ) ( bool , error )
Find many
Find one
Update many
var adults [] map [ string ] interface {}
err := users . Find ( "age >= 18" , & adults )
if err != nil {
log . Fatal ( err )
}
for _ , user := range adults {
fmt . Printf ( " %s is %v years old \n " , user [ "name" ], user [ "age" ])
}
Bulk operations
// Insert multiple documents
func ( c * Collection ) InsertMany ( docs [] interface {}) ([] string , error )
// Upsert by ID
func ( c * Collection ) UpsertByID ( id string , doc interface {}) ( * UpsertResult , error )
// Upsert with filter
func ( c * Collection ) Upsert ( filter string , doc interface {}) ( * UpsertResult , error )
Advanced operations
// Get distinct values for a field
func ( c * Collection ) Distinct ( field string ) ([] interface {}, error )
// Count distinct values
func ( c * Collection ) CountDistinct ( field string ) ( int64 , error )
// Full-text search
func ( c * Collection ) Search ( query string , result interface {}) error
// Count with filter
func ( c * Collection ) CountWithQuery ( filter string ) ( int64 , error )
// Query with all options
func ( c * Collection ) QueryWithOptions (
filter string ,
sortField string ,
sortAsc bool ,
limit uint64 ,
skip uint64 ,
projectFields [] string ,
excludeFields [] string ,
result interface {},
) error
Indexing
// Create a single-field index
func ( d * Database ) CreateIndex ( collectionName , indexName , field string , unique bool ) error
// Create a compound index
func ( d * Database ) CreateCompoundIndex ( collectionName , indexName string , fields [] string , unique bool ) error
// Create a full-text search index
func ( d * Database ) CreateTextIndex ( collectionName , indexName , field string ) error
// Drop an index
func ( d * Database ) DropIndex ( collectionName , indexName string ) error
// List indexes
func ( d * Database ) ListIndexes ( collectionName string ) ([] IndexInfo , error )
type IndexInfo struct {
Name string `json:"name"`
Fields [] string `json:"fields"`
Unique bool `json:"unique"`
BTreeRoot uint64 `json:"btree_root"`
}
Schema validation
// Set a JSON schema for validation
func ( d * Database ) SetSchema ( collectionName string , schema map [ string ] interface {}) error
// Get the current schema
func ( d * Database ) GetSchema ( collectionName string ) ( map [ string ] interface {}, error )
// Remove schema validation
func ( d * Database ) RemoveSchema ( collectionName string ) error
Maintenance
// Perform a manual checkpoint
func ( d * Database ) Checkpoint () error
// Create a backup
func ( d * Database ) Backup ( destPath string ) error
// Verify a backup file
func VerifyBackup ( backupPath string ) ( map [ string ] interface {}, error )
// Run garbage collection
func ( d * Database ) GarbageCollect () ( map [ string ] interface {}, error )
// Get database metrics
func ( d * Database ) Metrics () ( map [ string ] interface {}, error )
// Get frame count
func ( d * Database ) FrameCount () ( int64 , error )
Error handling
type Error struct {
Code int
Message string
}
func ( e * Error ) Error () string {
return e . Message
}
All operations return Go’s standard error interface:
id , err := tx . Insert ( "users" , doc )
if err != nil {
if dbErr , ok := err .( * jasonisnthappy . Error ); ok {
fmt . Printf ( "Database error [ %d ]: %s \n " , dbErr . Code , dbErr . Message )
} else {
fmt . Printf ( "Error: %s \n " , err )
}
return err
}
Requirements
CGO enabled (default on most systems)
Internet connection on first build (to download native library)
C compiler:
macOS : xcode-select --install
Linux : apt install build-essential or yum install gcc
Windows : Install MinGW-w64
macOS: ARM64 (Apple Silicon) and x64 (Intel)
Linux: ARM64 and x64
Windows: x64
Windows ARM64 is not currently supported.
Troubleshooting
Library download fails
Ensure you have internet connectivity
Check that the GitHub release exists with the required files
Verify your platform is supported
Build fails with CGO errors
Make sure you have a C compiler installed for your platform.
Static linking fails
Make sure you ran go generate first
Check that the .a file exists: ls bindings/go/lib/*/
Verify you have system dependencies installed