libidav/davqlparser.h

changeset 101
95a215337b53
parent 98
237844f263b4
child 102
e9ae1318a559
--- a/libidav/davqlparser.h	Sat May 02 10:59:02 2015 +0200
+++ b/libidav/davqlparser.h	Sat May 02 11:00:28 2015 +0200
@@ -46,7 +46,8 @@
  * Enumeration of possible expression types.
  */
 typedef enum {
-    DAVQL_LITERAL, DAVQL_IDENTIFIER,
+    DAVQL_UNDEFINED_TYP,
+    DAVQL_NUMBER, DAVQL_STRING, DAVQL_TIMESTAMP, DAVQL_IDENTIFIER,
     DAVQL_UNARY, DAVQL_BINARY, DAVQL_LOGICAL, DAVQL_FUNCCALL
 } davqlexprtype_t;
 
@@ -54,12 +55,12 @@
  * Enumeration of possible expression operators.
  */
 typedef enum {
-    DAVQL_NOOP,
+    DAVQL_NOOP, DAVQL_CALL, DAVQL_ARGLIST, // internal representations
     DAVQL_ADD, DAVQL_SUB, DAVQL_MUL, DAVQL_DIV,
-    DAVQL_AND, DAVQL_OR, DAVQL_XOR, DAVQL_NEG,
-    DAVQL_NOT, DAVQL_LAND, DAVQL_LOR, DAVQL_LXOR,
+    DAVQL_AND, DAVQL_OR, DAVQL_XOR, DAVQL_NEG,  // airthmetic
+    DAVQL_NOT, DAVQL_LAND, DAVQL_LOR, DAVQL_LXOR, // logical
     DAVQL_EQ, DAVQL_NEQ, DAVQL_LT, DAVQL_GT, DAVQL_LE, DAVQL_GE,
-    DAVQL_LIKE, DAVQL_UNLIKE
+    DAVQL_LIKE, DAVQL_UNLIKE // comparisons
 } davqloperator_t;
 
 /**
@@ -82,7 +83,6 @@
     davqlexprtype_t type;
     /**
      * Operator.
-     * 
      */
     davqloperator_t op;
     /**
@@ -97,6 +97,42 @@
     DavQLExpression *right;
 };
 
+/**
+ * A tuple representing an order criterion.
+ */
+typedef struct {
+    /**
+     * The column.
+     */
+    DavQLExpression *column;
+    /**
+     * True, if the result shall be sorted descending, false otherwise.
+     * Default is false (ascending).
+     */
+    _Bool descending;
+} DavQLOrderCriterion;
+
+/**
+ * A tuple representing a field.
+ */
+typedef struct {
+    /**
+     * The field name.
+     * <ul>
+     * <li>GET: the identifier or an alias name</li>
+     * <li>SET: the identifier</li>
+     * </ul>
+     */
+    sstr_t name;
+    /**
+     * The field expression.
+     * <ul>
+     * <li>GET: the queried property (identifier) or an expression</li>
+     * <li>SET: the expression for the value to be set</li>
+     * </ul>
+     */
+    DavQLExpression *expr;
+} DavQLField;
 
 /**
  * Query statement object.
@@ -110,13 +146,15 @@
  *            | FunctionCall | Identifier | Literal
  *            | "(", Expression, ")";
  * 
- * FunctionCall    = Identifier, "(", Expression, ")";
+ * FunctionCall    = Identifier, "(", ArgumentList, ")";
+ * ArgumentList    = Expression, {",", Expression};
  * Identifier      = IdentifierChar - ?Digit?, {IdentifierChar}
- *                 | "`", ?Character?, {?Character?}, "`";
- * IdentifierChar  = ?Character - (" "|",")?;
- * Literal         = Number | String;
+ *                 | "`", ?Character? - "`", {?Character? - "`"}, "`";
+ * IdentifierChar  = ?Character? - (" "|",");
+ * Literal         = Number | String | Timestamp;
  * Number          = ?Digit?, {?Digit?} | "%d";
- * String          = "'", {?Character - "'"? | "'''"} , "'";
+ * String          = "'", {?Character? - "'" | "'''"} , "'" | "%s";
+ * Timestamp       = "%t"; // TODO: maybe introduce a real literal 
  * 
  * LogicalExpression = LogicalExpression, LogicalOperator, LogicalExpression
  *                   | "not ", LogicalExpression
@@ -129,16 +167,23 @@
  * LogicalOperator = " and " | " or " | " xor ";
  * Comparison      = | "=" | "<" | ">" | "<=" | ">=" | "!=";
  * 
- * FieldExpressions = "*", {",", Expression, " as ", String}
+ * FieldExpressions = "*", {",", Expression, " as ", Identifier}
  *                  | FieldExpression, {",", FieldExpression}
  *                  | "-";
  * FieldExpression  = Identifier
- *                  | Expression, " as ", String;
- * SetExpressions   = SetExpression, {",", {SetExpressions};
+ *                  | Expression, " as ", Identifier;
+ * SetExpressions   = SetExpression, {",", SetExpressions};
  * SetExpression    = Identifier, "=", Expression;
  * 
+ * Path = "%s"
+ *      | "/", {?Character? - " "}
+ *      | "'/", {?Character?}, "'";
+ * 
  * WithClause = "depth", "=", (Number | "infinity");
  * 
+ * OrderByClause    = OrderByCriterion, {",", OrderByCriterion};
+ * OrderByCriterion = (Identifier | Number), [" asc"|" desc"];
+ * 
  * </pre>
  * 
  * Note: mandatory spaces are part of the grammar. But you may also insert an
@@ -148,17 +193,18 @@
  * <b>GET:</b>
  * <pre>
  * GetStatement = "get ", FieldExpressions,
- * " from ", Identifier,
+ * " from ", Path,
+ * [" with ", WithClause],
  * [" where ", LogicalExpression],
- * [" with ", WithClause];
+ * [" order by ", OrderByClause];
   * </pre>
  * 
  * <b>SET:</b>
  * <pre>
  * "set ",SetExpressions,
- * " at ", Identifier,
- * (" where ", LogicalExpression) | " anywhere",
- * [" with ", WithClause];
+ * " at ", Path,
+ * [" with ", WithClause],
+ * (" where ", LogicalExpression) | " anywhere";
  * </pre>
  * 
  */
@@ -180,15 +226,10 @@
      */
     char* errormessage;
     /**
-     * The list of field expressions.
+     * The list of DavQLFields.
      */
     UcxList* fields;
     /**
-     * The list of DavQLExpressions for the new DAV property values.
-     * This is <code>NULL</code> for GET queries.
-     */
-    UcxList* setvalues;
-    /**
      * A string that denotes the queried path.
      */
     sstr_t path;
@@ -198,8 +239,16 @@
      */
     DavQLExpression* where;
     /**
+     * The list of DavQLOrderCriterions.
+     * This is <code>NULL</code> for SET queries and may be <code>NULL</code>
+     * if the result doesn't need to be sorted.
+     */
+    UcxList* orderby;
+    /**
      * The recursion depth for the statement.
      * Defaults to 1.
+     * Magic numbers are DAV_DEPTH_INFINITY for infinity and
+     * DAV_DEPTH_PLACEHOLDER for a placeholder.
      */
     int depth;
 } DavQLStatement;
@@ -207,6 +256,45 @@
 /** Infinity recursion depth for a DavQLStatement. */
 #define DAV_DEPTH_INFINITY -1
 
+/** Depth needs to be specified at runtime. */
+#define DAV_DEPTH_PLACEHOLDER -2
+
+/** Invalid path. */
+#define DAVQL_ERROR_INVALID_PATH 1
+
+/** Expected an identifier, but found something else. */
+#define DAVQL_ERROR_IDENTIFIER_EXPECTED 10
+
+/** Expected an identifier or literal, but found something else. */
+#define DAVQL_ERROR_IDORLIT_EXPECTED 11
+
+/** Expected an identifier or number, but found something else. */
+#define DAVQL_ERROR_IDORNUM_EXPECTED 12
+
+/** Expected an identifier or string, but found something else. */
+#define DAVQL_ERROR_IDORSTR_EXPECTED 13
+
+/** Expected an identifier or timestamp, but found something else. */
+#define DAVQL_ERROR_IDORTS_EXPECTED 14
+
+/** The with-clause contains an unknown attribute. */
+#define DAVQL_ERROR_UNKNOWN_ATTRIBUTE 20
+
+/** Depth must be greater than zero or infinity. */
+#define DAVQL_ERROR_INVALID_DEPTH 21
+
+/** The with-clause contains an attribute more than once. */
+#define DAVQL_ERROR_DUPLICATED_ATTRIBUTE 29
+
+/** The format specifier is missing. */
+#define DAVQL_ERROR_MISSING_FMTSPEC 30
+
+/** The format specifier is unknown. */
+#define DAVQL_ERROR_UNKNOWN_FMTSPEC 31
+
+/** The format specifier is invalid. */
+#define DAVQL_ERROR_INVALID_FMTSPEC 39
+
 /** A quote symbol (' or `) is missing. */
 #define DAVQL_ERROR_MISSING_QUOTE 50
 

mercurial