data

package
v0.0.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2024 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Equal

func Equal(value1, value2 *structpb.Value) bool

Equal checks if two structpb.Value are equal

func JoinTables

func JoinTables(t1, t2 *Table, key1, key2 string, joinType JoinType) ([]map[string]interface{}, error)

JoinTables is a function that performs a join operation between two tables. It supports different types of joins: inner join, left join, right join, and full outer join. The join operation is based on the key fields provided for each table. The function first resets and loads the indexes for both tables. It then processes the records from the first table, attempting to find matching records in the second table based on the key fields. If a match is found, the records are merged and added to the results. If no match is found and the join type is a left join or full outer join, the record from the first table is added to the results alone. If the join type is a right join or full outer join, the function also processes the records from the second table. For each record in the second table, it checks if a matching record was found in the first table. If no matching record was found, the record from the second table is added to the results alone.

Parameters: - t1, t2: Pointers to the first and second Table objects to be joined. - key1, key2: The key fields for the first and second tables, respectively. - joinType: The type of join to be performed, represented as a JoinType value.

Returns: - A slice of maps, where each map represents a joined record. The keys in the map are field names and the values are the corresponding field values. - An error, if any error occurs during the join operation. If the operation is successful, the error is nil.

func ValidFilename added in v0.0.12

func ValidFilename(name string) bool

Types

type Database

type Database struct {
	sync.RWMutex                   // Mutex to ensure the database is thread safe
	Name         string            // Name of the database
	Tables       map[string]*Table // Map of Tables in the database
}

func NewDatabase

func NewDatabase(name string) *Database

func (*Database) CreateTable

func (db *Database) CreateTable(tableName, primaryKey string) error

CreateTable is a method of the Database struct that creates a new table in the database. It takes a table name and a primary key as arguments. The table name and primary key must match the regex `^[a-zA-Z0-9-_]+$`, meaning they can only contain alphanumeric characters, hyphens, and underscores. They cannot contain spaces, punctuation (except for hyphens and underscores), or special characters. It first checks if the table name and the primary key are valid using the ValidFilename function. If either the table name or the primary key is not valid, it returns an error. It then acquires a lock on the Database struct and defers the unlocking of the lock. It checks if a table with the same name already exists in the database. If a table with the same name already exists, it returns an error. It then creates the database directory if it does not exist. If there is an error creating the database directory, the error is returned. It creates a new Table instance with the primary key and the file path of the table. It adds the table to the Tables field of the Database struct. It then saves the primary key in a metadata file. If there is an error serializing the metadata or writing the metadata file, the error is returned. It then creates the initial file for the table. If there is an error creating the initial file, the error is returned. If the table is successfully created, the method returns nil.

func (*Database) ListTables

func (db *Database) ListTables() ([]string, error)

ListTables returns a list of tables in the database

func (*Database) LoadTables

func (db *Database) LoadTables(dbDir string) error

LoadTables loads the tables from the database directory.

type DatabaseReader

type DatabaseReader interface {
	ServeHTTP(w http.ResponseWriter, r *http.Request)
	ListTables(w http.ResponseWriter) []string
}

type ExecutionPlan

type ExecutionPlan struct {
	IndexToUse string                 // IndexToUse specifies the index to be used for the query.
	Filters    map[string]interface{} // Filters contains the filters to be applied to the query.
	SortBy     string                 // SortBy specifies the field to sort the query results by.
	Limit      int                    // Limit specifies the maximum number of results to be returned.
	Offset     int                    // Offset specifies the number of results to skip before returning.
}

ExecutionPlan represents the execution plan for a database query.

type JoinType

type JoinType int
const (
	InnerJoin JoinType = iota
	LeftJoin
	RightJoin
	FullOuterJoin
)

type Metrics added in v0.0.12

type Metrics struct {
	sync.RWMutex
	InsertCount int       // The number of insert operations performed.
	UpdateCount int       // The number of update operations performed.
	DeleteCount int       // The number of delete operations performed.
	QueryCount  int       // The number of query operations performed.
	CacheHits   int       // The number of successful cache retrievals.
	CacheMisses int       // The number of unsuccessful cache retrievals.
	LastInsert  time.Time // The timestamp of the last insert operation.
	LastUpdate  time.Time // The timestamp of the last update operation.
	LastDelete  time.Time // The timestamp of the last delete operation.
	LastQuery   time.Time // The timestamp of the last query operation.
}

Metrics is a structure that holds various counts and timestamps related to database operations and cache usage.

func NewMetrics added in v0.0.12

func NewMetrics() *Metrics

NewMetrics creates and returns a new Metrics structure.

func (*Metrics) IncrementCacheHits added in v0.0.12

func (m *Metrics) IncrementCacheHits()

IncrementCacheHits increases the count of successful cache retrievals.

func (*Metrics) IncrementCacheMisses added in v0.0.12

func (m *Metrics) IncrementCacheMisses()

IncrementCacheMisses increases the count of unsuccessful cache retrievals.

func (*Metrics) IncrementDeleteCount added in v0.0.12

func (m *Metrics) IncrementDeleteCount()

IncrementDeleteCount increases the count of delete operations and updates the timestamp of the last delete operation.

func (*Metrics) IncrementInsertCount added in v0.0.12

func (m *Metrics) IncrementInsertCount()

IncrementInsertCount increases the count of insert operations and updates the timestamp of the last insert operation.

func (*Metrics) IncrementQueryCount added in v0.0.12

func (m *Metrics) IncrementQueryCount()

IncrementQueryCount increases the count of query operations and updates the timestamp of the last query operation.

func (*Metrics) IncrementUpdateCount added in v0.0.12

func (m *Metrics) IncrementUpdateCount()

IncrementUpdateCount increases the count of update operations and updates the timestamp of the last update operation.

func (*Metrics) String added in v0.0.12

func (m *Metrics) String() string

String returns a string representation of the Metrics structure in JSON format.

type Query

type Query struct {
	Filters map[string]interface{} // Filters to select specific records
	SortBy  string                 // SortBy is a Field to sort the records by
	Limit   int                    // Limit is the Maximum number of records to return
	Offset  int                    // Offset is the Number of records to skip (for pagination)
}

The Query functionality allows you to perform complex queries on your database table. A query can include filters, sorting, limits, and offsets, which help in retrieving specific subsets of data efficiently.

type Record

type Record map[string]interface{}

type Server

type Server struct {
	sync.RWMutex                      // Mutex to ensure the server is thread safe
	Databases    map[string]*Database // Map of Databases in the server
}

func NewServer

func NewServer() *Server

NewServer creates a new Server instance. It initializes the Databases field as an empty map where the key is a string representing the database name and the value is a pointer to a Database instance. It returns a pointer to the newly created Server instance.

func (*Server) BackupDatabases added in v0.0.11

func (s *Server) BackupDatabases() (string, error)

BackupDatabases is a method of the Server struct that creates a backup of all databases in the server. It returns the path to the backup file and an error if there is one.

The method works as follows:

  1. It acquires a read lock on the Server struct and defers the unlocking of the lock.
  2. It creates a backup directory in the default backup directory. The default backup directory is determined by the getDefaultBackUpDir function. If there is an error creating the backup directory, the error is returned.
  3. It creates a backup file in the backup directory. The backup file is a zip file named "backup.zip". If there is an error creating the backup file, the error is returned.
  4. It creates a new zip writer for the backup file and defers the closing of the zip writer.
  5. It iterates over each database in the Databases field of the Server struct. For each database, it walks the database directory and adds each file to the zip file. The database directory is determined by the getDefaultServerDir function and the database name. If there is an error walking the database directory or adding a file to the zip file, the error is returned.
  6. If all databases are successfully backed up, the method returns the path to the backup file and nil.

func (*Server) CreateDatabase

func (s *Server) CreateDatabase(name string) error

CreateDatabase creates a new database in the server.

func (*Server) GetMetrics added in v0.0.12

func (s *Server) GetMetrics() map[string]string

func (*Server) Initialize

func (s *Server) Initialize() error

Initialize is a method of the Server struct that initializes the server. It creates the server directory and loads the databases. The server directory is determined by the getDefaultServerDir function. If the server directory does not exist, it is created with read, write, and execute permissions for the user only. If there is an error creating the server directory, the error is returned. After the server directory is successfully created or if it already exists, the databases are loaded using the LoadDatabases method. If there is an error loading the databases, the error is returned. If the server directory is successfully created and the databases are successfully loaded, the method returns nil.

func (*Server) ListDatabases

func (s *Server) ListDatabases() []string

ListDatabases returns a list of databases in the server.

func (*Server) LoadDatabases

func (s *Server) LoadDatabases() error

LoadDatabases is a method of the Server struct that loads the databases from the server directory. It reads the server directory using the os.ReadDir function and the getDefaultServerDir function. If there is an error reading the server directory, the error is returned. For each directory in the server directory, it creates a new Database instance with the directory name as the database name. It then loads the tables from the database directory using the LoadTables method of the Database struct. If there is an error loading the tables, the error is returned. If the tables are successfully loaded, the database is added to the Databases field of the Server struct. If all databases are successfully loaded, the method returns nil.

func (*Server) RestoreDatabases added in v0.0.11

func (s *Server) RestoreDatabases(backupPath ...string) error

RestoreDatabases is a method of the Server struct that restores databases from the latest backup file. It acquires a lock on the Server struct and defers the unlocking of the lock. It opens the latest backup file in the default backup directory. The default backup directory is determined by the getDefaultBackUpDir if the backup Path is empty, if there's not, the route will be checked. If there is an error opening the backup file, the error is returned. It gets the file stat of the backup file. If there is an error getting the file stat, the error is returned. It creates a new zip reader for the backup file. If there is an error creating the zip reader, the error is returned. It iterates over each file in the zip file. For each file, it creates the file path by joining the default server directory and the file name. The default server directory is determined by the getDefaultServerDir function. If the file is a directory, it creates the directory with read, write, and execute permissions for the user only. If the file is a regular file, it creates the file with the same permissions as in the zip file. It opens the file for writing. If there is an error opening the file, the error is returned. It opens the zip file for reading. If there is an error opening the zip file, the error is returned. It copies the contents of the zip file to the file. If there is an error copying the contents, the error is returned. It closes the file and the zip file. After all files are successfully restored, it loads the databases using the LoadDatabases method of the Server struct. If there is an error loading the databases, the error is returned. If all databases are successfully loaded, the method returns nil.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface for the server.

type Table

type Table struct {
	sync.RWMutex        // Mutex for read-write locking
	FilePath     string // Path to the file where the table data is stored
	PrimaryKey   string // Field name used as the primary key for the table

	Indexes map[string][]*dbdata.Record // Map of field names to slices of records that have that field
	Records map[string]*dbdata.Record   // Map of primary key values to the corresponding records
	Cache   map[string]*dbdata.Record   // Cache for recently accessed records
	// contains filtered or unexported fields
}

Table is a struct that represents a table in the database. It includes a mutex for read-write locking to ensure thread safety during operations. FilePath is the path to the file where the table data is stored. PrimaryKey is the field name that is used as the primary key for the table. utils is a utility object used for various helper functions. Indexes is a map where the keys are field names and the values are slices of records that have that field. Records is a map where the keys are primary key values and the values are the corresponding records.

func NewTable

func NewTable(primaryKey, filePath string) *Table

NewTable is a constructor function for the Table struct. It takes a primary key and a file path as arguments and returns a pointer to a new Table instance.

The function first gets the directory from the file path and checks if it exists. If the directory does not exist, it creates it with the appropriate permissions. It then creates a new Table instance, setting the FilePath, PrimaryKey, utils, Records, and Indexes fields. It calls the initializeFileIfNotExists method to ensure that the file where the table data is stored exists. If the file does not exist, it is created and initialized with an empty Records map. If an error occurs during this operation, the function logs the error and exits. It then calls the LoadIndexes method to load the indexes from the file into the Indexes map. If an error occurs during this operation, the function logs the error and exits. Finally, it returns the new Table instance.

Parameters: - primaryKey: A string representing the field name to be used as the primary key for the table. - filePath: A string representing the path to the file where the table data is stored.

Returns: - A pointer to a new Table instance.

func (*Table) Delete

func (t *Table) Delete(key interface{}) error

Delete is a method of the Table struct that deletes a record from the table based on the given key. It locks the table for writing, ensuring that no other goroutines can modify the table while the deletion is happening. It first reads all existing records from the file where the table data is stored. If the primary key of the record to be deleted does not exist in the table, it returns an error. It then removes the record from the main records map. It also updates the indexes. For each field in the record, it removes the record from the index for that field. If the index for a field becomes empty after the removal of the record, it deletes the index. It then writes the updated records back to the file. If any error occurs during these operations, it returns the error.

Parameters: - key: An interface{} representing the key of the record to be deleted. The key is converted to a string before the deletion is performed.

Returns: - If the operation is successful, it returns nil. - If an error occurs, it returns the error.

func (*Table) DeleteMany added in v0.0.13

func (t *Table) DeleteMany(keys []interface{}) []error

DeleteMany is a method of the Table struct that deletes multiple records from the table based on the given keys. It locks the table for writing, ensuring that no other goroutines can modify the table while the deletion is happening. It first reads all existing records from the file where the table data is stored. For each key, if the primary key of the record to be deleted does not exist in the table, it returns an error for that key but continues with the rest. It then removes the record from the main records map. It also updates the indexes. For each field in the record, it removes the record from the index for that field. If the index for a field becomes empty after the removal of the record, it deletes the index. It then writes the updated records back to the file. If any error occurs during these operations, it returns the error.

Parameters: - keys: A slice of interface{} representing the keys of the records to be deleted. The keys are converted to strings before the deletion is performed.

Returns: - A slice of errors for keys that failed to delete. If all records are deleted successfully, the slice is empty.

func (*Table) DeleteWithTransaction

func (t *Table) DeleteWithTransaction(key interface{}) error

DeleteWithTransaction is a method of the Table struct that performs a delete operation within a transaction context. It first creates a new transaction for the table. It then starts the transaction by locking the table and duplicating the records for potential rollback. If an error occurs while starting the transaction, it returns the error. It then tries to delete the record from the table with the given key. If an error occurs while deleting the record, it rolls back the transaction and returns the error. If the delete operation is successful, it commits the transaction and returns nil.

Parameters: - key: An interface{} representing the key of the record to be deleted. The key is converted to a string before the deletion is performed.

Returns: - If the operation is successful, it returns nil. - If an error occurs, it returns the error.

func (*Table) Insert

func (t *Table) Insert(record Record) error

func (*Table) InsertMany added in v0.0.13

func (t *Table) InsertMany(records []Record) error

InsertMany is a method of the Table struct that inserts multiple new records into the table. It divides the records into batches and inserts each batch separately to optimize performance. If an error occurs while inserting a batch, it is added to a slice of errors. After all batches have been processed, it returns the slice of errors.

Parameters: - records: A slice of maps representing the records to be inserted. The keys are field names and the values are the field values.

Returns: - A slice of errors for records that failed to insert. If all records are inserted successfully, the slice ismpty.

func (*Table) InsertWithTransaction

func (t *Table) InsertWithTransaction(record Record) error

InsertWithTransaction is a method of the Table struct that performs an insert operation within a transaction context. It first creates a new transaction for the table. It then starts the transaction by locking the table and duplicating the records for potential rollback. If an error occurs while starting the transaction, it returns the error. It then tries to insert the record into the table. If an error occurs while inserting the record, it rolls back the transaction and returns the error. If the insert operation is successful, it commits the transaction and returns nil.

Parameters: - record: A Record representing the record to be inserted into the table.

Returns: - If the operation is successful, it returns nil. - If an error occurs, it returns the error.

func (*Table) LoadIndexes

func (t *Table) LoadIndexes() error

LoadIndexes loads the indexes from the file

func (*Table) Query

func (t *Table) Query(query Query) ([]Record, error)

Query is a method of the Table struct that performs a query on the table and returns the resulting records. It first generates an execution plan for the given query. The execution plan includes the best index to use for the query, the filters to apply, the field to sort by, and the limit and offset for the results. It then executes the execution plan, searching for records that match the filters, sorting the results, and applying the limit and offset. If an error occurs during the execution of the plan, it returns the error.

Parameters: - query: A Query object representing the query to be performed. The Query object includes filters to select specific records, a field to sort the records by, and a limit and offset for the results.

Returns: - A slice of Record objects, representing the records that match the query. If no records match the query, it returns an empty slice. - An error, if any error occurs during the query operation. If the operation is successful, the error is nil.

func (*Table) ResetAndLoadIndexes

func (t *Table) ResetAndLoadIndexes() error

ResetAndLoadIndexes resets the indexes and reloads them from the file

func (*Table) Select

func (t *Table) Select(key interface{}) (Record, error)

Select is a method of the Table struct that selects a record from the table based on the given key. It locks the table for reading, ensuring that no other goroutines can modify the table while the selection is happening. It then reads all existing records from the file where the table data is stored. It converts the key to a string and checks if a record with that key exists in the table. If a record with that key does not exist, it returns an error and a nil record. If a record with that key exists, it returns the record and a nil error.

Parameters: - key: An interface{} representing the key of the record to be selected. The key is converted to a string before the selection is performed.

Returns: - A pointer to a dbdata.Record instance representing the record with the given key. - If a record with the given key does not exist, it returns an error and a nil record. - If an error occurs while reading the records from the file, it returns the error and a nil record. - If the operation is successful, it returns the record with the given key and a nil error.

func (*Table) SelectAll

func (t *Table) SelectAll() ([]Record, error)

SelectAll is a method of the Table struct that selects all records from the table. It locks the table for reading, ensuring that no other goroutines can modify the table while the selection is happening. It then reads all existing records from the file where the table data is stored. It iterates over the records, appending each one to a slice of records. If any error occurs during these operations, it returns the error and a nil slice. If the operation is successful, it returns the slice of all records and a nil error.

Returns: - A slice of pointers to dbdata.Record instances representing all records in the table. - If an error occurs, it returns the error and a nil slice. - If the operation is successful, it returns the slice of all records and a nil error.

func (*Table) SelectWithFilter

func (t *Table) SelectWithFilter(filters map[string]interface{}) ([]Record, error)

SelectWithFilter is a method of the Table struct that selects records from the table based on the given filters. It locks the table for reading, ensuring that no other goroutines can modify the table while the selection is happening. It then reads all existing records from the file where the table data is stored. It iterates over the records, checking each one against the filters. For each record, it iterates over the filters. For each filter, it converts the filter value to a proto Value. If an error occurs during this conversion, it returns the error and a nil slice. It then checks if the field specified by the filter exists in the record and if the value of the field in the record is equal to the filter value. If the field does not exist in the record or if the values are not equal, it skips to the next record. If all filters match for a record, it appends the record to a slice of matched records. If the operation is successful, it returns the slice of matched records and a nil error.

Parameters: - filters: A map where the keys are field names and the values are the filter values. Only records where the field values match the filter values are selected.

Returns: - A slice of pointers to dbdata.Record instances representing the records that match the filters. - If an error occurs, it returns the error and a nil slice. - If the operation is successful, it returns the slice of matched records and a nil error.

func (*Table) Update

func (t *Table) Update(key interface{}, updates Record) error

Update is a method of the Table struct that updates a record in the table based on the given key. It locks the table for writing, ensuring that no other goroutines can modify the table while the update is happening. It first reads all existing records from the file where the table data is stored. If the primary key of the record to be updated does not exist in the table, it returns an error. It then iterates over the fields in the updates map, updating each field in the existing record. For each field, it checks if the field exists in the existing record. If the field exists, it removes the existing record from the index for that field. It then converts the new field value to a proto Value and updates the field in the existing record. If an error occurs during this conversion, it returns the error. It then adds the updated record to the index for the field. If the index for the field does not exist, it initializes it before adding the updated record. It then writes the updated records back to the file. If any error occurs during these operations, it returns the error.

Parameters: - key: An interface{} representing the key of the record to be updated. The key is converted to a string before the update is performed. - updates: A map representing the fields to be updated in the record. The keys are field names and the values are the new field values.

Returns: - If the operation is successful, it returns nil. - If an error occurs, it returns the error.

func (*Table) UpdateMany added in v0.0.13

func (t *Table) UpdateMany(updates map[string]Record) []error

UpdateMany is a method of the Table struct that updates multiple records in the table based on the given keys and updates. It locks the table for writing, ensuring that no other goroutines can modify the table while the updates are happening. It first reads all existing records from the file where the table data is stored. For each key, if the primary key of the record to be updated does not exist in the table, it returns an error for that key but continues with the rest. It then iterates over the fields in the updates map, updating each field in the existing record. For each field, it checks if the field exists in the existing record. If the field exists, it removes the existing record from the index for that field. It then converts the new field value to a proto Value and updates the field in the existing record. If an error occurs during this conversion, it returns an error for that record but continues with the rest. It then adds the updated record to the index for the field. If the index for the field does not exist, it initializes it before adding the updated record. It then writes the updated records back to the file. If any error occurs during these operations, it returns an error for that record but continues with the rest.

Parameters: - updates: A map where the keys are the primary key values and the values are the updates to be applied to the records. Each value is a map representing the fields to be updated.

Returns: - A slice of errors for records that failed to update. If all records are updated successfully, the slice is empty.

func (*Table) UpdateWithTransaction

func (t *Table) UpdateWithTransaction(key interface{}, updates Record) error

UpdateWithTransaction is a method of the Table struct that performs an update operation within a transaction context. It first creates a new transaction for the table. It then starts the transaction by locking the table and duplicating the records for potential rollback. If an error occurs while starting the transaction, it returns the error. It then tries to update the record in the table with the given key and updates. If an error occurs while updating the record, it rolls back the transaction and returns the error. If the update operation is successful, it commits the transaction and returns nil.

Parameters: - key: An interface{} representing the key of the record to be updated. The key is converted to a string before the update is performed. - updates: A Record representing the fields to be updated in the record. The keys are field names and the values are the new field values.

Returns: - If the operation is successful, it returns nil. - If an error occurs, it returns the error.

type Transaction

type Transaction struct {
	sync.Mutex                                // Mutex to ensure the transaction is thread safe
	OriginalRecords map[string]*dbdata.Record // Map to hold the original records
	Table           *Table                    // Table to which the transaction belongs
}

This srtuct holds the transaction data for managing the transaction

func NewTransaction

func NewTransaction(table *Table) *Transaction

Creates a new transaction with the table

func (*Transaction) Commit

func (t *Transaction) Commit() error

Commit ends the transaction by unlocking it, indicating successful completion of all operations

func (*Transaction) Rollback

func (t *Transaction) Rollback() error

Rollback ends the transaction by unlocking it and writing the original records back to the file

func (*Transaction) Start

func (t *Transaction) Start() error

Start begins the transaction by locking the table and duplicating the records for potential rollback

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL