Documentation
¶
Index ¶
- Constants
- Variables
- func ConvertSQLCommands(lines []string) []string
- func InterfaceToSQLString(interfaceVal interface{}) string
- func PrintDebug(msg string)
- func SecondToMs(s float64) float64
- func SecondToMsString(s float64) string
- func ToInsertSQLRawFromSlice(records []DBRecord) []string
- func TotalTimeElapsedInSecond(reses []BasicSQLResult) float64
- type BasicSQLResult
- type Condition
- type DBRecord
- type DBRecords
- type DataStruct
- type Database
- type NodeStatusStruct
- type ParametereizedSQL
- type SchemaStruct
- type StatusStruct
- type TableStruct
Constants ¶
const ( DEFAULT_PAGINATION_LIMIT = 50 DEFAULT_MAX_MULTIPLE_INSERTS = 100 // Maximum number of rows to insert in a single SQL statement )
Variables ¶
var ( // Some global vars are needed so we can change this on the fly later on. // For example: we read the MAX_MULTIPLE_INSERTS from db.settings then // it will be changed on the fly when function that need this variable got called! ErrSQLNoRows medaerror.MedaError = medaerror.MedaError{Message: "select returns no rows"} ErrSQLMoreThanOneRow medaerror.MedaError = medaerror.MedaError{Message: "select returns more than 1 rows"} MAX_MULTIPLE_INSERTS int = DEFAULT_MAX_MULTIPLE_INSERTS )
Functions ¶
func ConvertSQLCommands ¶
Convert the .sql file into each individual sql commands Input is []string which are the content of the .sql file Output is []string of each sql commands.
func InterfaceToSQLString ¶
func InterfaceToSQLString(interfaceVal interface{}) string
func SecondToMs ¶
func SecondToMsString ¶
func ToInsertSQLRawFromSlice ¶
ToInsertSQLRawFromSlice converts a slice of DBRecord to a slice of raw SQL statements by converting to DBRecords first
func TotalTimeElapsedInSecond ¶
func TotalTimeElapsedInSecond(reses []BasicSQLResult) float64
Get all sum timing
Types ¶
type BasicSQLResult ¶
mostly used for rawSQL execution, this is the return, empty if it's not applicable This is not for query where we return usually DBRecord or DBRecords / []DBRecord
type Condition ¶
type Condition struct {
Field string `json:"field,omitempty" db:"field"`
Operator string `json:"operator,omitempty" db:"operator"`
Value interface{} `json:"value,omitempty" db:"value"`
Logic string `json:"logic,omitempty" db:"logic"` // "AND" or "OR"
Nested []Condition `json:"nested,omitempty" db:"nested"` // For nested conditions
OrderBy []string `json:"order_by,omitempty" db:"order_by"` // Fields to order by
GroupBy []string `json:"group_by,omitempty" db:"group_by"` // Fields to group by
Limit int `json:"limit,omitempty" db:"limit"` // Limit for pagination
Offset int `json:"offset,omitempty" db:"offset"` // Offset for pagination
}
Condition struct for query filtering with JSON and DB tags This struct is used to define conditions for filtering data in queries. It supports various operations like AND, OR, and nested conditions. Sample usage:
// Simple condition
condition := Condition{
Field: "age",
Operator: ">",
Value: 18,
}
// Output: WHERE age > 18
// Nested condition with AND logic
condition := Condition{
Logic: "AND",
Nested: []Condition{
Condition{Field: "age", Operator: ">", Value: 18},
Condition{Field: "status", Operator: "=", Value: "active"},
},
}
// Output: WHERE (age > 18 AND status = 'active')
// Nested condition with OR logic
condition := Condition{
Logic: "OR",
Nested: []Condition{
Condition{Field: "status", Operator: "=", Value: "pending"},
Condition{Field: "status", Operator: "=", Value: "review"},
},
}
// Output: WHERE (status = 'pending' OR status = 'review')
// Complex condition with nested AND and OR
condition := Condition{
Logic: "OR",
Nested: []Condition{
Condition{
Logic: "AND",
Nested: []Condition{
Condition{Field: "age", Operator: ">", Value: 18},
Condition{Field: "country", Operator: "=", Value: "USA"},
},
},
Condition{
Logic: "AND",
Nested: []Condition{
Condition{Field: "status", Operator: "=", Value: "active"},
Condition{Field: "role", Operator: "=", Value: "admin"},
},
},
},
}
// Output: WHERE ((age > 18 AND country = 'USA') OR (status = 'active' AND role = 'admin'))
func (*Condition) And ¶
And creates a new Condition with AND logic for the given conditions. This method allows chaining multiple conditions together with AND logic. Usage:
condition.And(
Condition{Field: "age", Operator: ">", Value: 18},
Condition{Field: "status", Operator: "=", Value: "active"}
)
Returns: A new Condition with nested conditions joined by AND
func (*Condition) Or ¶
Or creates a new Condition with OR logic for the given conditions. This method allows chaining multiple conditions together with OR logic. Usage:
condition.Or(
Condition{Field: "status", Operator: "=", Value: "pending"},
Condition{Field: "status", Operator: "=", Value: "review"}
)
Returns: A new Condition with nested conditions joined by OR
func (*Condition) ToSelectString ¶
ToSelectString generates a complete SELECT SQL query string with WHERE, GROUP BY, ORDER BY, and LIMIT/OFFSET clauses based on the Condition struct. Usage:
query, values := condition.ToSelectString("users")
Returns:
- string: Complete SELECT query (e.g., "SELECT * FROM users WHERE age > ? ORDER BY name LIMIT 10")
- []interface{}: Slice of values for the parameterized query
func (*Condition) ToWhereString ¶
ToWhereString converts a Condition struct into a WHERE clause string and parameter values. It handles nested conditions recursively and supports both AND/OR logic. Usage:
whereClause, values := condition.ToWhereString()
Returns:
- string: SQL WHERE clause with parameterized queries (e.g., "field1 = ? AND (field2 > ?)")
- []interface{}: Slice of values corresponding to the parameters
type DBRecord ¶
func TableStructToDBRecord ¶
func TableStructToDBRecord(obj TableStruct) (DBRecord, error)
func (*DBRecord) FromStruct ¶
func (d *DBRecord) FromStruct(obj TableStruct) error
FromStruct converts a TableStruct object to a DBRecord. It maps the struct fields to the DBRecord's Data map and sets the table name. Usage:
var record DBRecord record.FromStruct(userStruct)
Returns: error if conversion fails
func (*DBRecord) ToInsertSQLParameterized ¶
Convert DBRecord to SQL Insert string and values but with placeholder (parameterized) ToInsertSQLParameterized converts a single DBRecord to a parameterized INSERT SQL statement. Usage:
sql, values := record.ToInsertSQLParameterized()
Returns:
- string: Parameterized INSERT query (e.g., "INSERT INTO table (col1, col2) VALUES (?, ?)")
- []interface{}: Slice of values for the parameters
func (*DBRecord) ToInsertSQLRaw ¶
Convert DBRecord to SQL Insert string and values ToInsertSQLRaw converts a single DBRecord to a raw INSERT SQL statement with values. Usage:
sql, values := record.ToInsertSQLRaw()
Returns:
- string: Complete INSERT query with values (e.g., "INSERT INTO table (col1, col2) VALUES ('value1', 2)")
- []interface{}: Slice of original values (for reference)
type DBRecords ¶
type DBRecords []DBRecord
func DBRecordsFromSlice ¶
DBRecordsFromSlice converts a slice of DBRecord to DBRecords type and uses the DBRecords methods
func (*DBRecords) Append ¶
Append adds a new DBRecord to the DBRecords slice. Usage:
records.Append(newRecord)
func (DBRecords) ToInsertSQLParameterized ¶
func (records DBRecords) ToInsertSQLParameterized() []ParametereizedSQL
NOTE: For not same tables that are in DBRecords then use the DBRecord.ToInsertSQLParameterized() function for each record in DBRecords.
BULK inserts, one is parameterized and non-parameterized (just plain raw SQL) This is always for same table only, not for different tables!
ToInsertSQLParameterized converts multiple DBRecords to a slice of parameterized INSERT statements. It automatically batches inserts according to MAX_MULTIPLE_INSERTS limit. Usage:
statements := records.ToInsertSQLParameterized()
Returns: Slice of ParametereizedSQL containing batched INSERT statements and their values
func (DBRecords) ToInsertSQLRaw ¶
ToInsertSQLRaw converts multiple DBRecords to a slice of raw INSERT SQL statements. It automatically batches inserts according to MAX_MULTIPLE_INSERTS limit. Usage:
statements := records.ToInsertSQLRaw()
Returns: Slice of strings containing complete INSERT statements with values
type DataStruct ¶
type DataStruct struct {
TypeDef string // string | int | bool | etc
Value interface{}
Empty bool // this to replace the nil value if data is not set
}
TODO: replace the DBRecord.Data to be map[string]DataStruct . this will be more robust and flexible
type Database ¶
type Database interface {
GetSchema(bool, bool) []SchemaStruct
Status() (NodeStatusStruct, error)
SelectOne(string) (DBRecord, error) // This is almost unusable, very rare case
SelectMany(string) (DBRecords, error) // This is almost unusable, very rare case (this is like select ALL rows from the table)
SelectOneWithCondition(string, *Condition) (DBRecord, error)
SelectManyWithCondition(string, *Condition) ([]DBRecord, error)
SelectOneSQL(string) (DBRecords, error) // select using one sql statement
SelectManySQL([]string) ([]DBRecords, error) // select using many sql statements
SelectOnlyOneSQL(string) (DBRecord, error) // select only returning 1 row, and also check if actually more than 1 return errors
SelectOneSQLParameterized(ParametereizedSQL) (DBRecords, error) // select using one parameterized sql statement
SelectManySQLParameterized([]ParametereizedSQL) ([]DBRecords, error) // select using many parameterized sql statements
SelectOnlyOneSQLParameterized(ParametereizedSQL) (DBRecord, error) // select only returning 1 row, and also check if actually more than 1 return errors
ExecOneSQL(string) BasicSQLResult
ExecOneSQLParameterized(ParametereizedSQL) BasicSQLResult
ExecManySQL([]string) ([]BasicSQLResult, error)
ExecManySQLParameterized([]ParametereizedSQL) ([]BasicSQLResult, error)
InsertOneDBRecord(DBRecord, bool) BasicSQLResult
InsertManyDBRecords([]DBRecord, bool) ([]BasicSQLResult, error)
InsertManyDBRecordsSameTable([]DBRecord, bool) ([]BasicSQLResult, error)
// TableStruct is less practical
InsertOneTableStruct(TableStruct, bool) BasicSQLResult
InsertManyTableStructs([]TableStruct, bool) ([]BasicSQLResult, error)
// Status and Health check
IsConnected() bool
Leader() (string, error) // this was originally for RQLite, if not then just return empty string or "not implemented"
Peers() ([]string, error) // this was originally for RQLite, if not then just return empty string or "not implemented"
}
type NodeStatusStruct ¶
type NodeStatusStruct struct {
StatusStruct
Peers map[int]StatusStruct // all peers including the leader
}
NodeStatusStruct is a struct that contains the status of a node, including its peers (if has peers) It is mostly derived from the SettingsTable but is used for response. Mode is : r , w, or rw (for read only, write only and read and write) Example of how to use it:
var nodeStatus NodeStatusStruct
nodeStatus.StatusStruct = StatusStruct{...}
nodeStatus.Peers = map[int]StatusStruct{...}
Output:
{
"url": "http://localhost:4001",
"version": "3.5.0",
"start_time": "2022-01-01T00:00:00Z",
"uptime": "24h0m0s",
"dir_size": 1024,
"db_size": 2048,
"node_id": "node1",
"is_leader": true,
"leader": "node1",
"last_backup": "2022-01-01T00:00:00Z",
"mode": "standalone",
"nodes": 1,
"node_number": 1,
"peers": {
2: {
"url": "http://localhost:4002",
"version": "3.5.0",
"start_time": "2022-01-01T00:00:00Z",
"uptime": "24h0m0s",
"dir_size": 1024,
"db_size": 2048,
"node_id": "node2",
"is_leader": false,
"leader": "node1",
"last_backup": "2022-01-01T00:00:00Z",
"mode": "r",
"nodes": 2,
"node_number": 2
}
}
}
func (*NodeStatusStruct) PrintPretty ¶
func (s *NodeStatusStruct) PrintPretty()
This function is used to print the status of the node in a pretty format, including its peers. Example of how to use it: s.PrintPretty() Output: A formatted string representation of the node's status and its peers. This is mainly for debugging and logging
type ParametereizedSQL ¶
type ParametereizedSQL struct {
Query string `json:"query"`
Values []interface{} `json:"values,omitempty"`
}
func SQLAndValuesToParameterized ¶
func SQLAndValuesToParameterized(q string, p []interface{}) ParametereizedSQL
func ToInsertSQLParameterizedFromSlice ¶
func ToInsertSQLParameterizedFromSlice(records []DBRecord) []ParametereizedSQL
ToInsertSQLParameterizedFromSlice converts a slice of DBRecord to a slice of ParametereizedSQL by converting to DBRecords first
type SchemaStruct ¶
type SchemaStruct struct {
ObjectType string `json:"type" db:"type"`
ObjectName string `json:"name" db:"name"`
TableName string `json:"tbl_name" db:"tbl_name"`
RootPage int `json:"rootpage" db:"rootpage"`
SQLCommand string `json:"sql" db:"sql"`
Hidden bool `json:"hidden" db:"hidden"`
}
Struct to get the schema from sqlite_master table in SQLite
func (SchemaStruct) PrintDebug ¶
func (s SchemaStruct) PrintDebug(sql bool)
PrintDebug prints debug information about a database schema object. If sql parameter is true, it includes the SQL command in the output. Usage:
schema.PrintDebug(true)
Output Example:
Object [table] : users[users_table] - CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)
type StatusStruct ¶
type StatusStruct struct {
URL string `json:"url,omitempty" db:"url"` // URL (host + port)
Version string `json:"version,omitempty" db:"version"` // version of the DMBS
DBMS string `json:"dbms,omitempty" db:"dbms"` // version of the DMBS
DBMSDriver string `json:"dbms_driver,omitempty" db:"dbms_driver"` // version of the DMBS
StartTime time.Time `json:"start_time,omitempty" db:"start_time"`
Uptime time.Duration `json:"uptime,omitempty" db:"uptime"`
DirSize int64 `json:"dir_size,omitempty" db:"dir_size"` // if applicable
DBSize int64 `json:"db_size,omitempty" db:"db_size"` // if applicable
NodeID string `json:"node_id,omitempty" db:"node_id"` // DBMS node ID, was rqlite node_id from status
IsLeader bool `json:"is_leader,omitempty" db:"is_leader"`
Leader string `json:"leader,omitempty" db:"leader"` // complete address (including protocol, ie: https://...)
LastBackup time.Time `json:"last_backup,omitempty" db:"last_backup"` // if applicable
Mode string `json:"mode,omitempty" db:"mode"` // options are r, w, or rw
Nodes int `json:"nodes,omitempty" db:"nodes"` // total number of nodes in the cluster
NodeNumber int `json:"node_number,omitempty" db:"node_number"` // this node number, actually this is not applicable in rqlite, because NodeID is string
MaxPool int `json:"max_pool,omitempty" db:"max_pool"` // if applicable
}
Struct to use as per-node status, information mostly from SettingsTable, but this is used for response
func (*StatusStruct) PrintPretty ¶
func (s *StatusStruct) PrintPretty(indent, title string)
This function is used to print the status of a node in a pretty format, mainly for debugging and logging purposes. Example usage: nodeStatus.PrintPretty("", "Node Status") Output: A formatted string representation of the node's status, including URL, version, start time, uptime, directory size, database size, node ID, leadership status, leader ID, last backup time, mode, number of nodes, and node number. This is mainly for debugging and logging
type TableStruct ¶
type TableStruct interface {
TableName() string
}
Make sure other table struct that you use implement this method