Documentation ¶
Overview ¶
Package rpc implements functions and structs for plugins to communicate with the main program
All exported elements prefixed with "Internal" are not meant to be used by plugins but by programs that communicate with plugins
We strongly recommend looking at the introduction to plugins in the README.md before looking at this package
Index ¶
- Constants
- type ColumnConstraint
- type ColumnType
- type ConnectionPool
- type DatabaseSchema
- type DatabaseSchemaColumn
- type DeleteArgs
- type InitializeArgs
- type InsertArgs
- type InternalClient
- type InternalExchangeInterface
- type InternalPlugin
- type NewClientParams
- type Operator
- type OrderConstraint
- type Plugin
- type PluginConfig
- func (p PluginConfig) GetBool(key string) bool
- func (p PluginConfig) GetBoolArray(key string) []bool
- func (p PluginConfig) GetFloat(key string) float64
- func (p PluginConfig) GetFloatArray(key string) []float64
- func (p PluginConfig) GetInt(key string) int64
- func (p PluginConfig) GetIntArray(key string) []int64
- func (p PluginConfig) GetString(key string) string
- func (p PluginConfig) GetStringArray(key string) []string
- type PluginConfigField
- type PluginManifest
- type PluginRPCClient
- func (m *PluginRPCClient) Close(connectionID int) error
- func (m *PluginRPCClient) Delete(connectionID int, tableIndex int, primaryKeys []interface{}) error
- func (m *PluginRPCClient) Initialize(connectionID int, tableIndex int, config PluginConfig) (DatabaseSchema, error)
- func (m *PluginRPCClient) Insert(connectionID int, tableIndex int, rows [][]interface{}) error
- func (m *PluginRPCClient) Query(connectionID int, tableIndex int, cursorIndex int, constraint QueryConstraint) ([][]interface{}, bool, error)
- func (m *PluginRPCClient) Update(connectionID int, tableIndex int, rows [][]interface{}) error
- type PluginRPCServer
- func (m *PluginRPCServer) Close(connectionID int, resp *struct{}) error
- func (m *PluginRPCServer) Delete(args *DeleteArgs, resp *struct{}) error
- func (m *PluginRPCServer) Initialize(args *InitializeArgs, resp *DatabaseSchema) error
- func (m *PluginRPCServer) Insert(args *InsertArgs, resp *struct{}) error
- func (m *PluginRPCServer) Query(args *QueryArgs, resp *QueryReturn) error
- func (m *PluginRPCServer) Update(args *UpdateArgs, resp *struct{}) error
- type QueryArgs
- type QueryConstraint
- type QueryReturn
- type ReaderInterface
- type Table
- type TableCreator
- type TableCreatorArgs
- type UpdateArgs
Constants ¶
const ( // OperatorEqual is the equal operator = OperatorEqual = 2 // OperatorGreater is the greater than operator > OperatorGreater = 4 // OperatorLessOrEqual is the less than or equal operator <= OperatorLessOrEqual = 8 // OperatorLess is the less than operator < OperatorLess = 16 // OperatorGreaterOrEqual is the greater than or equal operator >= OperatorGreaterOrEqual = 32 // OperatorMatch is the match operator OperatorMatch = 64 // OperatorLike is the like operator OperatorLike = 65 // OperatorGlob is the glob operator. // It represents a simple pattern matching operator // with a UNIX syntax // // Note: A like operator is not provided because anyquery // converts it to a glob operator OperatorGlob = 66 // OperatorRegexp is the regexp operator OperatorRegexp = 67 // OperatorNotEqual is the not equal operator != OperatorNotEqual = 68 // OperatorISNOT is the IS NOT operator // // Note: will be converted to OperatorNotEqual OperatorIsNot = 69 // OperatorISNOTNULL is the IS NOT NULL operator // // Note: will be converted to OperatorNotEqual with value nil OperatorIsNotNull = 70 // OperatorISNULL is the IS NULL operator // // Note: will be converted to OperatorEqual with value nil OperatorIsNull = 71 // OperatorIS is the IS operator // // Note: will be converted to OperatorEqual OperatorIs = 72 // OperatorLimit is the LIMIT statement in a SQL query OperatorLimit = 73 // OperatorOFFSET is the OFFSET statement in a SQL query OperatorOffset = 74 )
const MagicCookieKey = "ANYQUERY_PLUGIN"
const MagicCookieValue = "1.0.0"
const ProtocolVersion = 1
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ColumnConstraint ¶
func (*ColumnConstraint) GetBoolValue ¶ added in v0.1.3
func (cc *ColumnConstraint) GetBoolValue() bool
Returns the bool value of the column constraint
If the value is not a bool, it'll try to convert it to a bool If it fails or the constraints does not exist, it returns false
func (*ColumnConstraint) GetFloatValue ¶ added in v0.1.2
func (cc *ColumnConstraint) GetFloatValue() float64
Returns the float value of the column constraint
If the value is not a float, it'll try to convert it to a float If it fails or the constraints does not exist, it returns 0
func (*ColumnConstraint) GetIntValue ¶ added in v0.1.2
func (cc *ColumnConstraint) GetIntValue() int64
Returns the int value of the column constraint
If the value is not an int, it'll try to convert it to an int If it fails or the constraints does not exist, it returns 0
func (*ColumnConstraint) GetStringValue ¶ added in v0.1.2
func (cc *ColumnConstraint) GetStringValue() string
Returns the string value of the column constraint
If the value is not a string, it'll try to convert it to a string If it fails or the constraints does not exist, it returns an empty string
func (*ColumnConstraint) GetTimeValue ¶ added in v0.1.3
func (cc *ColumnConstraint) GetTimeValue() time.Time
Returns the time value of the column constraint
If the value is not a time.Time, it'll try to convert it to a time.Time If it fails or the constraints does not exist, it returns the zero value of time.Time
Supported formats are:
- time.RFC3339
- time.RFC822
- time.RubyDate
- time.UnixDate
- time.DateTime
- time.DateOnly
- Unix timestamp (int64 or float64)
func (*ColumnConstraint) IsEqual ¶ added in v0.1.2
func (cc *ColumnConstraint) IsEqual() bool
Whether the column constraint is the equal operator
type ColumnType ¶
type ColumnType int8
ColumnType is an enum that represents the type of a column
const ( // ColumnTypeInt represents an INTEGER column ColumnTypeInt ColumnType = iota // ColumnTypeFloat represents a REAL column ColumnTypeFloat // ColumnTypeString represents a TEXT column ColumnTypeString // ColumnTypeBlob represents a BLOB column ColumnTypeBlob // ColumnTypeBool represents is an alias for ColumnTypeInt ColumnTypeBool = ColumnTypeInt )
type ConnectionPool ¶
type ConnectionPool struct {
// contains filtered or unexported fields
}
ConnectionPool is a struct that holds the connections to the plugins It allows using the same executable for multiple connections
It is not intended to be used by plugins but by the main program
func NewConnectionPool ¶
func NewConnectionPool() *ConnectionPool
NewConnectionPool creates a new connection pool
Using the zero value is not recommended and might lead to a SIGSEGV
func (*ConnectionPool) CloseConnection ¶
func (c *ConnectionPool) CloseConnection(executableLocation string, connectionID int)
Warn the plugin that the connection will be closed, wait a few seconds and close the connection If all connections are closed, the plugin is killed
func (*ConnectionPool) NewClient ¶
func (c *ConnectionPool) NewClient(params NewClientParams) (*InternalClient, error)
Request a new client from the connection pool. Each NewClient must be followed by a CloseConnection. If these requirements are not met, the executable will not be killed
type DatabaseSchema ¶
type DatabaseSchema struct { // The columns of the table Columns []DatabaseSchemaColumn // The primary key is the index of the column where each row has a unique value // // If set to -1, it means the table does not have a primary key. // Therefore, the main program will generate a unique key for each row. // However, the table won't be able to update or delete rows. // // The primary key column type is either ColumnTypeInt or ColumnTypeString PrimaryKey int // Whether the plugin can handle an INSERT statement HandlesInsert bool // Whether the plugin can handle an UPDATE statement HandlesUpdate bool // Whether the plugin can handle a DELETE statement HandlesDelete bool // HandleOffset is a boolean that specifies whether the plugin can handle the OFFSET clause. // If not, the main program will skip the n offseted rows. HandleOffset bool // How many rows should anyquery buffer before sending them to the plugin // // If set to 0, the main program will send the rows one by one // It is used to reduce the number of API calls of plugins BufferInsert uint // How many rows should anyquery buffer before sending them to the plugin // // If set to 0, the main program will send the rows one by one // It is used to reduce the number of API calls of plugins BufferUpdate uint // How many rows should anyquery buffer before sending them to the plugin // // If set to 0, the main program will send the rows one by one // It is used to reduce the number of API calls of plugins BufferDelete uint }
DatabaseSchema holds the schema of the database
It must stay the same throughout the lifetime of the plugin and for every cursor opened.
One and only field must be the primary key. If you don't have a primary key, you can generate a unique key. The primary key must be unique for each row. It is used to update and delete rows.
type DatabaseSchemaColumn ¶
type DatabaseSchemaColumn struct { // The name of the column Name string // The type of the column (INTEGER, REAL, TEXT, BLOB) Type ColumnType // Whether the column is a parameter // // If a column is a parameter, it will be hidden from the user // in the result of a SELECT query // and can be passed as an argument of the table // // For example, a parameter column named account_id // can be used as such // SELECT * FROM mytable(<account_id>) // SELECT * FROM mytable WHERE account_id = <account_id> // // Arguments order is the same as the order of the columns in the schema IsParameter bool // Whether the column is required // // If a column is required, the user must provide a value for it. // If not, the query will fail. IsRequired bool // A description of the column // Not used by early versions of anyquery Description string }
type DeleteArgs ¶
type InitializeArgs ¶
type InitializeArgs struct { ConnectionID int TableIndex int Config PluginConfig }
InitializeArgs is a struct that holds the arguments for the Initialize method
It's necessary to define this struct because the arguments for the RPC methods are passed as a single argument
type InsertArgs ¶
type InternalClient ¶
type InternalClient struct { Client *go_plugin.Client Plugin InternalExchangeInterface }
type InternalExchangeInterface ¶
type InternalExchangeInterface interface { // Initialize is called when a new table is opened // // It is used by the main program to infer the schema of the tables Initialize(connectionID int, tableIndex int, config PluginConfig) (DatabaseSchema, error) // Query is a method that returns rows for a given SELECT query // // Constraints are passed as arguments for optimization purposes // However, the plugin is free to ignore them because // the main program will filter the results to match the constraints // // The first return value is a 2D slice of interface{} where each row is a slice // and each element in the row is an interface{} representing the value. // The second return value is a boolean that specifies whether the cursor is exhausted // The order and type of the values should match the schema of the table Query(connectionID int, tableIndex int, cursorIndex int, constraint QueryConstraint) ([][]interface{}, bool, error) // Insert is a method that inserts rows into the table // // The rows are passed as a 2D slice of interface{} where each row is a slice // and each element in the row is an interface{} representing the value. Insert(connectionID int, tableIndex int, rows [][]interface{}) error // Update is a method that updates rows in the table // // The rows are passed as a 2D slice of interface{} where each row is a slice // and each element in the row is an interface{} representing the value. Update(connectionID int, tableIndex int, rows [][]interface{}) error // Delete is a method that deletes rows from the table // // The rows are passed as an array of primary keys Delete(connectionID int, tableIndex int, primaryKeys []interface{}) error // Close is a method that is called when the connection is closed // // It is used to free resources and close connections Close(connectionID int) error }
InternalExchangeInterface is an interface that defines the methods that a plugin must implement to communicate with the main program
This part should be handled by the plugin library and should not be implemented by the user
type InternalPlugin ¶
type InternalPlugin struct {
Impl InternalExchangeInterface
}
type NewClientParams ¶
type OrderConstraint ¶
type Plugin ¶
type Plugin struct {
// contains filtered or unexported fields
}
Plugin represents a plugin that can be loaded by anyquery
func (*Plugin) RegisterTable ¶
func (p *Plugin) RegisterTable(tableIndex int, tableCreator TableCreator) error
RegisterTable registers a new table to the plugin
The tableIndex must be unique and match the index in the manifest
type PluginConfig ¶
type PluginConfig map[string]interface{}
PluginConfig is a struct that holds the configuration for the plugin
It is mostly used to specify user-defined configuration and is passed to the plugin during initialization
func (PluginConfig) GetBool ¶ added in v0.1.2
func (p PluginConfig) GetBool(key string) bool
Returns a bool value for the key in the plugin configuration
If the key does not exist or is not a bool, it returns false
func (PluginConfig) GetBoolArray ¶ added in v0.1.2
func (p PluginConfig) GetBoolArray(key string) []bool
Returns a bool array for the key in the plugin configuration
If the key does not exist or is not a bool array, it returns nil
func (PluginConfig) GetFloat ¶ added in v0.1.2
func (p PluginConfig) GetFloat(key string) float64
Returns a float value for the key in the plugin configuration
If the key does not exist or is not a float, it returns 0
func (PluginConfig) GetFloatArray ¶ added in v0.1.2
func (p PluginConfig) GetFloatArray(key string) []float64
Returns a float array for the key in the plugin configuration
If the key does not exist or is not a float array, it returns nil
func (PluginConfig) GetInt ¶ added in v0.1.2
func (p PluginConfig) GetInt(key string) int64
Returns an int value for the key in the plugin configuration
If the key does not exist or is not an int, it returns 0
func (PluginConfig) GetIntArray ¶ added in v0.1.2
func (p PluginConfig) GetIntArray(key string) []int64
Returns an int array for the key in the plugin configuration
If the key does not exist or is not an int array, it returns nil
func (PluginConfig) GetString ¶ added in v0.1.2
func (p PluginConfig) GetString(key string) string
Returns a string value for the key in the plugin configuration
If the key does not exist or is not a string, it returns an empty string
func (PluginConfig) GetStringArray ¶ added in v0.1.2
func (p PluginConfig) GetStringArray(key string) []string
Returns a string array for the key in the plugin configuration
If the key does not exist or is not a string array, it returns nil
type PluginConfigField ¶
type PluginManifest ¶
type PluginManifest struct { Name string Version string Author string Description string // A list of tables that the plugin will provide Tables []string UserConfig []PluginConfigField }
PluginManifest is a struct that holds the metadata of the plugin
It is often represented as a JSON file in the plugin directory
type PluginRPCClient ¶
type PluginRPCClient struct {
// contains filtered or unexported fields
}
PluginRPCClient is a struct that holds the RPC client that will be called from the main program
func (*PluginRPCClient) Close ¶
func (m *PluginRPCClient) Close(connectionID int) error
func (*PluginRPCClient) Delete ¶
func (m *PluginRPCClient) Delete(connectionID int, tableIndex int, primaryKeys []interface{}) error
func (*PluginRPCClient) Initialize ¶
func (m *PluginRPCClient) Initialize(connectionID int, tableIndex int, config PluginConfig) (DatabaseSchema, error)
func (*PluginRPCClient) Insert ¶
func (m *PluginRPCClient) Insert(connectionID int, tableIndex int, rows [][]interface{}) error
func (*PluginRPCClient) Query ¶
func (m *PluginRPCClient) Query(connectionID int, tableIndex int, cursorIndex int, constraint QueryConstraint) ([][]interface{}, bool, error)
type PluginRPCServer ¶
type PluginRPCServer struct {
Impl InternalExchangeInterface
}
PluginRPCServer is a struct that holds the RPC server that will be runned by the plugin for the main program
func (*PluginRPCServer) Close ¶
func (m *PluginRPCServer) Close(connectionID int, resp *struct{}) error
func (*PluginRPCServer) Delete ¶
func (m *PluginRPCServer) Delete(args *DeleteArgs, resp *struct{}) error
func (*PluginRPCServer) Initialize ¶
func (m *PluginRPCServer) Initialize(args *InitializeArgs, resp *DatabaseSchema) error
func (*PluginRPCServer) Insert ¶
func (m *PluginRPCServer) Insert(args *InsertArgs, resp *struct{}) error
func (*PluginRPCServer) Query ¶
func (m *PluginRPCServer) Query(args *QueryArgs, resp *QueryReturn) error
func (*PluginRPCServer) Update ¶
func (m *PluginRPCServer) Update(args *UpdateArgs, resp *struct{}) error
type QueryArgs ¶
type QueryArgs struct { ConnectionID int TableIndex int CursorIndex int Constraint QueryConstraint }
QueryArgs is a struct that holds the arguments for the Query method (see InitializeArgs)
type QueryConstraint ¶
type QueryConstraint struct { // The constraints for each column (can be skipped and SQLite will handle it) Columns []ColumnConstraint // The maximum number of rows to return // // If set to -1, it means no limit Limit int // The number of rows to skip // // If set to -1, it means no offset Offset int // The order by constraints (can be skipped and SQLite will handle it) OrderBy []OrderConstraint }
QueryConstraint is a struct that holds the constraints for a SELECT query
It specifies the WHERE conditions in the Columns field, the LIMIT and OFFSET in the Limit and Offset fields, and the ORDER BY clause in the OrderBy field
func (QueryConstraint) GetColumnConstraint ¶ added in v0.1.2
func (qc QueryConstraint) GetColumnConstraint(columnID int) *ColumnConstraint
Returns the column constraint for the given column at the index columnID
If the column does not exist, it returns nil
type QueryReturn ¶
type QueryReturn struct { Rows [][]interface{} NoMoreRows bool }
type ReaderInterface ¶
type ReaderInterface interface { // Query is a method that returns rows for a given SELECT query // // Constraints are passed as arguments for optimization purposes // However, the plugin is free to ignore them because // the main program will filter the results to match the constraints // // The first return value is a 2D slice of interface{} where each row is a slice // and each element in the row is an interface{} representing the value. // The second return value is a boolean that specifies whether the cursor is exhausted // The order and type of the values should match the schema of the table Query(constraint QueryConstraint) ([][]interface{}, bool, error) }
ReaderInterface is an interface that must be implemented by the plugin
It maps the methods required by anyquery to work
type Table ¶
type Table interface { // CreateReader must return a new instance of a table reader // A table can have several concurrent readers for better performance CreateReader() ReaderInterface // Insert is called when the main program wants to insert rows // // The rows are passed as a 2D slice of interface{} where each row is a slice // and each element in the row is an interface{} representing the value. // // interface{} can be an int, string, int64, float64, []byte or nil Insert(rows [][]interface{}) error // Update is called when the main program wants to update rows // // The rows are passed as a 2D slice of interface{} where each row is a slice // and each element in the row is an interface{} representing the value. // // The primary key is at the index specified in the schema and is also at the first index of the row. // It is used to update the value of the primary key in the row. The first value is the former value // and the second value is the new value. // // interface{} can be an int, string, int64, float64, []byte or nil Update(rows [][]interface{}) error // Delete is called when the main program wants to delete rows // // The primary keys are passed as an array of interface{} Delete(primaryKeys []interface{}) error // Close is called when the connection is closed // // It is used to free resources and close connections Close() error }
Represents a table in the plugin
If your table doesn't support insert, update or delete, you should specify it in the schema and the according methods will not be called. They can return an error or nil
type TableCreator ¶
type TableCreator func(args TableCreatorArgs) (Table, *DatabaseSchema, error)
TableCreator is a function that creates a new table interface and returns the schema of the table
type TableCreatorArgs ¶
type TableCreatorArgs struct { // UserConfig is the configuration passed by the user // during the configuration of the plugin profile UserConfig PluginConfig // TableIndex is the index of the table in the manifest (0-based) TableIndex int // ConnectionID is the index of the connection. // It is used to identify the connection in the plugin and can change between restarts ConnectionID int }
Args passed to the TableCreator function
Implementation details: args are passed as a struct so that if we add more arguments in the future, old plugins will still work