Documentation
¶
Overview ¶
Package classifier provides tools to classify Cypher queries as either read-only or write operations.
It uses a keyword-based and procedure-based approach to determine the query's nature. The main entry point is the `Classify` method on a `QueryClassifier` object. The classifier is designed to be conservative, defaulting to classifying unknown procedures as write operations to ensure safety in read-only environments.
It can handle: - Standard Cypher keywords (MATCH, CREATE, MERGE, etc.). - Multi-word keywords (DETACH DELETE, ORDER BY). - Comments and string literals, which are ignored during classification. - Procedure calls (CALL db.labels), with predefined lists of known read/write procedures. - Subqueries (CALL { ... }), checking for write operations within the subquery block.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type QueryClassification ¶
type QueryClassification struct {
// Type is the overall classification of the query (READ or WRITE).
Type QueryType
// Confidence is a score from 0.0 to 1.0 indicating the classifier's certainty.
// 1.0 is fully confident. Lower scores may be assigned for ambiguous cases,
// like unknown procedures.
Confidence float64
// WriteTokens is a list of keywords or procedures found that indicate a write operation.
WriteTokens []string
// ReadTokens is a list of keywords or procedures found that indicate a read operation.
ReadTokens []string
// HasSubquery is true if the query contains a `CALL { ... }` block.
HasSubquery bool
// Error holds any error that occurred during classification, though this is not
// currently used in the implementation.
Error error
}
QueryClassification represents the detailed result of a query classification.
type QueryClassifier ¶
type QueryClassifier struct {
// contains filtered or unexported fields
}
QueryClassifier contains the logic and data for classifying Cypher queries. It should be instantiated via the NewQueryClassifier() function.
func NewQueryClassifier ¶
func NewQueryClassifier() *QueryClassifier
NewQueryClassifier creates and initializes a new QueryClassifier instance. It pre-compiles regular expressions and populates the internal lists of known Cypher keywords and procedures.
func (*QueryClassifier) AddReadProcedure ¶
func (c *QueryClassifier) AddReadProcedure(pattern string)
AddReadProcedure allows users to dynamically add a custom procedure prefix to the list of known read procedures. The pattern is matched using `strings.HasPrefix`.
Usage example:
classifier := NewQueryClassifier()
classifier.AddReadProcedure("my.custom.reader")
result := classifier.Classify("CALL my.custom.reader.getData()")
// result.Type will be ReadQuery
func (*QueryClassifier) AddWriteProcedure ¶
func (c *QueryClassifier) AddWriteProcedure(pattern string)
AddWriteProcedure allows users to dynamically add a custom procedure prefix to the list of known write procedures. This is useful for environments with custom plugins. The pattern is matched using `strings.HasPrefix`.
Usage example:
classifier := NewQueryClassifier()
classifier.AddWriteProcedure("my.custom.writer")
result := classifier.Classify("CALL my.custom.writer.createUser()")
// result.Type will be WriteQuery
func (*QueryClassifier) Classify ¶
func (c *QueryClassifier) Classify(query string) QueryClassification
Classify analyzes a Cypher query string and returns a QueryClassification result. It is the main method for this package.
The process is as follows: 1. Normalize the query by removing comments and extra whitespace. 2. Replace string literals to prevent keywords inside them from being classified. 3. Unify multi-word keywords (e.g., "DETACH DELETE" becomes "DETACH_DELETE"). 4. Extract all procedure calls (e.g., `CALL db.labels`). 5. Tokenize the remaining query string. 6. Check tokens and procedures against known read/write lists. 7. If a subquery `CALL { ... }` exists, check its contents for write operations. 8. Assign a final classification and confidence score.
Usage example:
classifier := NewQueryClassifier()
query := "MATCH (n:Person) WHERE n.name = 'Alice' SET n.age = 30"
result := classifier.Classify(query)
fmt.Printf("Query is a %s query with confidence %f\n", result.Type, result.Confidence)
// Output: Query is a WRITE query with confidence 0.900000
fmt.Printf("Write tokens found: %v\n", result.WriteTokens)
// Output: Write tokens found: [SET]