-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgobdb.go
125 lines (116 loc) · 3.59 KB
/
gobdb.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Package gobdb provides a simple key-value database for Go binary objects
// encoded with encoding/gob.
package gobdb
import (
"encoding/gob"
"errors"
"fmt"
"io"
"os"
)
// Gobdb represents a simple key-value database for Go binary objects encoded
// with encoding/gob. It is a generic type that can store any type of data in
// its Data field. The path field is unexported and contains the path to the
// file where the database is stored.
//
// The Gobdb type parameter T is constrained by the 'any' type constraint, meaning
// it can be any Go type.
//
// Fields:
//
// Data: A slice of type T. It contains the values of the database.
// path: A string representing the path to the file where the database is stored.
type Gobdb[T any] struct {
Data []T
path string
}
// Open is a generic function that opens a file at the specified path and
// decodes its contents using the gob decoder. The type of the data in the
// file should be specified as the type argument T when calling this function.
//
// The type parameter T is constrained by the 'any' type constraint, meaning
// it can be any Go type.
//
// If the decoding fails, it returns an error. If the decoding is successful,
// it returns a Gobdb object with the decoded data.
//
// Parameters:
//
// path: A string representing the path to the file to open and decode.
//
// Returns:
//
// A Gobdb object containing the decoded data, and a nil error if the
// operation was successful. If an error occurred, the Gobdb object will
// be empty and the error will contain details about what went wrong.
func Open[T any](path string) (Gobdb[T], error) {
var t T
gob.Register(t)
file, err := os.OpenFile(path, os.O_RDONLY|os.O_CREATE, 0644)
if err != nil {
return Gobdb[T]{}, err
}
defer file.Close()
decoder := gob.NewDecoder(file)
var data []T
err = decoder.Decode(&data)
if err != nil {
if !errors.Is(err, io.EOF) {
return Gobdb[T]{}, err
}
}
return Gobdb[T]{
Data: data,
path: path,
}, nil
}
// List is a method on the Gobdb type that returns all the data in the
// database as a slice. The type of the data returned is the same as the type
// parameter T of the Gobdb object.
//
// The type parameter T is constrained by the 'any' type constraint, meaning
// it can be any Go type.
//
// This method does not take any parameters.
//
// Returns:
//
// A slice of type T containing all the data in the database.
func (db Gobdb[T]) List() []T {
return db.Data
}
// Add is a method on the Gobdb type that adds new data to the database and
// persists the updated database to disk. The data to be added should be of
// the same type as the type parameter T of the Gobdb object.
//
// The type parameter T is constrained by the 'any' type constraint, meaning
// it can be any Go type.
//
// The method uses the path stored in the Gobdb object to open the file and
// encodes the updated data using the gob encoder. If an error occurs during
// this process, it returns an error.
//
// Parameters:
//
// d: A variadic parameter of type T representing the data to add to the
// database.
//
// Returns:
//
// If the operation is successful, the method returns nil. If an error occurs
// during the process, the method returns the error with details about what
// went wrong.
func (db *Gobdb[T]) Add(d ...T) error {
file, err := os.OpenFile(db.path, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
return fmt.Errorf("unable to open file: %w", err)
}
defer file.Close()
db.Data = append(db.Data, d...)
encoder := gob.NewEncoder(file)
err = encoder.Encode(&db.Data)
if err != nil {
return fmt.Errorf("unable to encode collection: %w", err)
}
return nil
}