Skip to content

Implement Query conditions #9

@chouzar

Description

@chouzar

These are just a couple of early ideas


Condition Algebra

pub fn filter(query: Query, condition: Condition(x)) -> Query {
  let conditions = [Condition(x), ..query.conditions]
  Function(..query, conditions: conditions)
}

type Condition(x) {
  Eq(Condition(x), Condition(x))
  Lt(Condition(x), Condition(x))
  Gt(Condition(x), Condition(x))
  Not(Condition(x))
  // Negates its single argument (anything other than false gives false).
  And(List(Condition(x)))
  // Returns true if all its arguments (variable length argument list) evaluate to true, otherwise false.
  Or(List(Condition(x)))
  // Returns true if any of its arguments evaluates to true. Variable length argument list. Evaluation order is undefined.
  Xor(Condition(x), Condition(x))
  // Only two arguments, of which one must be true and the other false to return true; otherwise 'xor' returns false.
  Length(List(Condition(x)))
  Max(Condition(x), Condition(x))
  Min(Condition(x), Condition(x))
  BitSize(Condition(x))
  ByteSize(Condition(x))
  TupleSize(Condition(x))
  BinaryPart(Condition(x))
}

Builder pattern

Have an API that composes matchspecs together with a builder pattern:

let query =
  q.new()                                  // Builds a basic default match function.
  |> q.bind(Person)                        // Modifies the head to match the constructor.
  |> q.match(field: 5, "Citizen")          // Modifies the head to match the value.
  |> q.where(field: 3, op: ">=", than: 18) // Adds a condition expression.

query |> q.select(object())                // Returns the whole object #(index, record).
query |> q.select(index())                 // Returns just the index of record.
query |> q.select(#(v(2), v(1)))           // Returns the 2nd and 1st variables in a tuple.
query |> q.select(False)                   // Returns false for each matching record.
query |> q.select(Driver)                  // Maps the variables to a constructor.
query |> q.select(fn(last, first) {        // Alternative mapper to above.
  Driver(last, first)
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions