Skip to content

Commit

Permalink
Resolves #2 - Support GORM
Browse files Browse the repository at this point in the history
  • Loading branch information
steve-r-west committed Mar 21, 2023
1 parent c894159 commit d07ef1d
Show file tree
Hide file tree
Showing 13 changed files with 2,216 additions and 1 deletion.
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# See GitHub's docs for more information on this file:
# https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every weekday
interval: "daily"

# Maintain dependencies for Go modules
- package-ecosystem: "gomod"
directory: "/"
schedule:
# Check for updates to Go modules every weekday
interval: "daily"
51 changes: 51 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# This GitHub action runs your tests for each commit push and/or PR. Optionally
# you can turn it on using a cron schedule for regular testing.
#
name: Tests
on:
push:
paths-ignore:
- 'README.md'
# For systems with an upstream API that could drift unexpectedly (like most SaaS systems, etc.),
# we recommend testing at a regular interval not necessarily tied to code changes. This will
# ensure you are alerted to something breaking due to an API change, even if the code did not
# change.
# schedule:
# - cron: '0 13 * * *'
jobs:
# ensure the code builds...
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.19'
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v3

- name: Get dependencies
run: |
go mod download
- name: Check go style
run: |
echo "If this command fails you should run go fmt \"./...\""
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
echo "Code style differences detected:"
gofmt -s -l -d .
exit 1
fi
- name: Build
run: |
go build ./...
- name: Unit Tests
timeout-minutes: 15
run: |
go test -v -cover ./...
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
# ep-search-ast-helper
# EPCC Search AST Helper

## Introduction

This project is designed to help consume the `EP-Internal-Search-Ast-v*` headers



142 changes: 142 additions & 0 deletions external/epsearchast/v3/ast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package epsearchast_v3

import (
"encoding/json"
"fmt"
"strings"
)

type AstNode struct {
NodeType string `json:"type"`
Children []AstNode `json:"children"`
FirstArg string `json:"first_arg"`
SecondArg string `json:"second_arg"`
Args []string `json:"args"`
}

func GetAst(jsonTxt string) (*AstNode, error) {
astNode := &AstNode{}

err := json.Unmarshal([]byte(jsonTxt), astNode)

if err != nil {
return nil, fmt.Errorf("could not parse filter:%w", err)
} else if err := astNode.checkValid(); err != nil {
return nil, fmt.Errorf("error validating filter:%w", err)
} else {
return astNode, nil
}
}

type AstVisitor interface {
PreVisit() error
PostVisit() error
PreVisitAnd(astNode *AstNode) (bool, error)
PostVisitAnd(astNode *AstNode) (bool, error)
VisitIn(astNode *AstNode) (bool, error)
VisitEq(astNode *AstNode) (bool, error)
VisitLe(astNode *AstNode) (bool, error)
VisitLt(astNode *AstNode) (bool, error)
VisitGe(astNode *AstNode) (bool, error)
VisitGt(astNode *AstNode) (bool, error)
VisitLike(astNode *AstNode) (bool, error)
}

func (a *AstNode) Accept(v AstVisitor) error {
err := v.PreVisit()

if err != nil {
return err
}

err = a.accept(v)

if err != nil {
return err
}

return v.PostVisit()
}

func (a *AstNode) accept(v AstVisitor) error {

var descend = false
var err error = nil

switch a.NodeType {
case "AND":
descend, err = v.PreVisitAnd(a)
case "IN":
descend, err = v.VisitIn(a)
case "EQ":
descend, err = v.VisitEq(a)
case "LE":
descend, err = v.VisitLe(a)
case "LT":
descend, err = v.VisitLt(a)
case "GT":
descend, err = v.VisitGt(a)
case "GE":
descend, err = v.VisitGe(a)
case "LIKE":
descend, err = v.VisitLike(a)
default:
return fmt.Errorf("unknown operator %s", a.NodeType)
}

if err != nil {
return err
}

if descend {
for _, c := range a.Children {
err = c.accept(v)
if err != nil {
return err
}
}
}

switch a.NodeType {
case "AND":
descend, err = v.PostVisitAnd(a)

if err != nil {
return err
}
}

return nil
}

func (a *AstNode) checkValid() error {
switch a.NodeType {
case "AND":
for _, c := range a.Children {
err := c.checkValid()
if err != nil {
return err
}
}
if len(a.Children) < 2 {
return fmt.Errorf("and should have at least two children")
}
case "IN":
if len(a.Args) < 2 {
return fmt.Errorf("insufficient number of arguments to in")
}

if len(a.Children) > 0 {
return fmt.Errorf("in should not have any children")
}
case "EQ", "LE", "LT", "GT", "GE", "LIKE":
if len(a.Children) > 0 {
return fmt.Errorf("operator %v should not have any children", strings.ToLower(a.NodeType))
}
default:
return fmt.Errorf("unknown operator %s", a.NodeType)
}

return nil

}
Loading

0 comments on commit d07ef1d

Please sign in to comment.