Skip to content

Latest commit

 

History

History
246 lines (205 loc) · 9.05 KB

espressopp-sdd.adoc

File metadata and controls

246 lines (205 loc) · 9.05 KB

Espresso++: Software Design Document

1. Introduction

1.1. Purpose of the Document

This document presents the design of Espresso++, a natural query language that abstracts the native query language of any data management system, and the intended audience is anybody involved in its realization.

1.2. Scope of the "Software Design Document"

This design document applies to any Skeeter API that supports data filtering.

1.3. Definitions, Acronyms, and Abbreviations

Lexer

The part of an interpreter that attaches meaning by classifying lexemes (string of symbols from the input) as particular tokens. For example, the lexemes or, and, and not are classified as logical operators by the Espresso++ lexer.

Parser

The part of an interpreter that attaches meaning by classifying strings of tokens from the input (sentences) as particular non-terminals and by building the parse tree. For example, token strings like [number][operator][number] or [id][operator][id] are classified as non-terminal expressions by the Espresso++ parser.

Interpreter

A computer program that converts each high-level statement into code or instructions that can be understood by the underlying system.

Visitor Pattern

A way of separating an algorithm from the structure on which it operates. The result of this separation is the ability to add new operations to an existing structure without modifying the structure itself.

References

1.4. Overview

Skeeter APIs let clients specify a filter to limit or control the data returned by an endpoint. A filter consists of one or more statements written in Espresso++ [1] that abstract away the native query language of the underlying data management system.

Espresso++ comes as a module together with a command-line utility that converts input Espresso++ expressions into native expressions that can be understood by the underlying data management system. The next sections describe what functionality Espresso++ shall provide and how that functionality shall be implemented.

2. Use Case View

Figure Actors, Use Cases, and their Interactions shows what functionality Espresso++ provides and what external systems (actors) interact with it.

Client << Aplication >>
(Interpret Espresso++ Script) as (uc1)
(Generate Native Code) as (uc2)
Client -> (uc1)
(uc1) ..> (uc2) : use
Actors, Use Cases, and their Interactions


Use case Interpret Espresso++ Script is started by the Client when an Espresso++ expression is executed to filter the data returned by an API endpoint. Interpret Espresso++ Script parses the Espresso++ expression and passes the resulting parse tree to use case Generate Native Code, which in turn generates the native query to be executed by the underlying data management system.

3. Logical View

This section describes the logical structure of Espresso++. The Espresso++ interpreter provides functionality for translating Espresso++ expressions into native queries. Figure Key Structural and Behavioral Elements shows the classes that make up Espresso++ and how they depend on each other.

abstract class Interpreter <<interface>> {
  +Accept(CodeGenerator, Reader, Writer)
  +Parse(Reader): Grammar
}
class EspressoppInterpreter {
  +Accept(CodeGenerator, Reader, Writer)
  +Parse(Reader): Grammar
}
abstract class CodeGenerator <<interface>> {
  +Visit(Interpreter, Reader, Writer)
}
class SqlCodeGenerator {
  +RenderingOptions: RenderingOptions
  +Visit(Interpreter, Reader, Writer)
}
class FieldProps {
  +Filterable: Bool
  +NativeName: String
}
class RenderingOptions {
  +AddFieldProps(String, FieldProps)
  +GetFieldProps(String): FieldProps
  +DeleteFieldProps(String): FieldProps
}
class Parser{
  +Parse(Reader): Grammar
}
class Grammar{
  +Query: {}
}
Client ..> Interpreter
Client ..> CodeGenerator
Interpreter <|-- EspressoppInterpreter : extends
note left: Call CodeGenerator.Visit(Interpreter, ...)
CodeGenerator <|-- SqlCodeGenerator : extends
SqlCodeGenerator o-- RenderingOptions
RenderingOptions ||--|{ FieldProps
EspressoppInterpreter o-- Parser
Grammar --* Parser
Key Structural and Behavioral Elements


The design of Espresso++ is based on the visitor pattern so that new CodeGenerator implementations can be added anytime without the need to modify EspressoppInterpreter. SqlCodeGenerator is the default CodeGenerator implementation shipped with the first release of Espresso++.

3.1. Use Case Realization

This section describes how the use cases are implemented and examines how the various design structures contribute to the functionality of the system. It also describes the collaborations that realize Espresso++ and contribute to define the dynamic view of the system.

3.1.1. Use Case: Interpret Espresso++ Script

This section describes the relationship between use case Interpret Espresso++ Script and the collaborations that actually realize it.

Scenario: Interpret Espresso++ Script

The sequence diagram depicted in figure Scenario Interpret Espresso++ Script describes how an Espresso++ script is interpreted into a native query.

actor Client
create EspressoppInterpreter
Client --> EspressoppInterpreter : new
create Parser
EspressoppInterpreter --> Parser : new
create Reader
Client --> Reader : new
create Writer
Client --> Writer : new
create SqlCodeGenerator
Client --> SqlCodeGenerator : new
Client -> EspressoppInterpreter : Accept(codeGenerator, reader, writer)
activate EspressoppInterpreter
EspressoppInterpreter -> SqlCodeGenerator : Visit(interpreter, reader, writer)
activate SqlCodeGenerator
SqlCodeGenerator -> EspressoppInterpreter : Parse(reader)
EspressoppInterpreter -> Parser : Parse(reader)
activate Parser
Parser -> Reader : Read()
activate Reader
return script
return grammar
EspressoppInterpreter --> SqlCodeGenerator : grammar
deactivate EspressoppInterpreter
SqlCodeGenerator -> SqlCodeGenerator : generateSql
activate SqlCodeGenerator
return sql
SqlCodeGenerator -> Writer : Write(sql)
activate Writer
deactivate SqlCodeGenerator
deactivate Writer
Client -> Writer : String()
activate Writer
return sql
Scenario Interpret Espresso++ Script


The Interpreter is initialized by the Client and provides functionality for parsing Espresso++ scripts to be converted into native queries by the CodeGenerator. The CodeGenerator is also initialized by the Client and gets accepted together with the Reader and Writer by the Interpreter — this construct allows the CodeGenerator to access the Parser instantiated by the Interpreter and get back the Espresso++ grammar.

The Reader is where the Espresso++ script is read from by the Parser, whereas the Writer is where the CodeGenerator writes the resulting native query.

By default field names in the input Espresso++ expression remain unchanged in the output native query. Should not the fields in the Espresso++ expression match the name of the fields in the underlying database, a mapping needs to be provided by means of the RenderingOptions.

The RenderingOptions is used by CodeGenerator implementations to control the way output queries are generated, and it might be associated with one or more FieldProps instances. A FieldProps specifies the native name of the field and whether it can be queried.

4. Process View

The process view describes the concurrent aspects of the system, namely the tasks (or processes) that make the system run and the interactions between them. Espresso++ is a module to be included into other applications. However, Espresso++ ships with a command-line utility that takes an Espresso++ espression as an input and returns the resulting native query.

The diagram depicted in figure Process Composition describes the process composition of the Espresso++ command-line utility and the mapping of resources on it.

class espressopp <<process>> {
  interpreter: EspressoppInterpreter
  codeGenerator: SqlCodeGenerator
  reader: io.Reader
  writer: io.Writer
}
Process Composition


The Espresso++ command-line utility uses the Interpreter and CodeGenerator exactly the same way client applications do. It is just meant to help developers debug filters written in the Espresso++ language.


Copyright © 2020 Skeeter Health