All files / src/lexer lexer.ts

95.45% Statements 21/22
50% Branches 1/2
100% Functions 5/5
94.74% Lines 18/19
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93  15x 15x     24x     24x   24x 238x     24x 24x                     16x 16x 16x   16x   16x                                                             5x 5x                             5x                 77x     15x  
import { Query } from "../reader/query";
import { Keyword } from "./tokens";
import { StatementFactory } from "./statementFactory";
 
function categorise(query: string) {
  query = query.trim().toLowerCase();
 
  // Cast the Keyword enum so we can to lookups on it without TypeScript complaining.
  const keywordLookup: { [keywordName: string]: string } = Keyword as any;
 
  const result = Object.keys(Keyword).find(keyword =>
    query.startsWith(keywordLookup[keyword])
  );
 
  Eif (result) {
    return keywordLookup[result];
  }
 
  throw new Error(
    `Unable to categorise query: ${query}. The query must start with one of ${Object.keys(
      Keyword
    )}`
  );
}
 
function tokenise(query: Query): Query {
  const category = categorise(query.getContent());
  const statementFactory = new StatementFactory();
  const statement = statementFactory.build(category);
 
  query.category = category;
 
  return statement.tokenise(query);
}
 
/*
 *
 * extractTableReference('symfony.gigs') => [
 *     'database': 'symfony',
 *     'table': 'gigs'
 * ]
 *
 * extractTableReference('symfony.gigs.venue') => [
 *     'database': 'symfony',
 *     'table': 'gigs',
 *     'column': 'venue'
 * ]
 *
 * extractTableReference('gigs.venue') => [
 *     'table': 'gigs',
 *     'column': 'venue'
 * ]
 *
 * extractTableReference('venue') => [
 *     'column': 'venue'
 * ]
 *
 * Assumptions:
 *   - A value on its own e.g. "venue" is assumed to be a table.
 *   - 3 values e.g. "symfony.gigs.venue" is assumed to be database.table.column
 *   - 2 values is assumed to be database.table
 */
function extractTableReference(tableReference: string) {
  const references = tableReference.split(".");
  const extractedReferences: any = {
    3: {
      database: references[0],
      table: references[1],
      column: references[2]
    },
    2: {
      database: references[0],
      table: references[1]
    },
    1: {
      table: references[0]
    }
  };
 
  return extractedReferences[references.length];
}
 
/**
 * Removes any invalid characters from an unquoted identifier.
 * This can be a database, table, column name etc...
 */
function cleanUnquotedIdentifier(identifier: string) {
  // Remove anything that isn't an a-z 0-9 or an _
  return identifier.replace(/([^a-z0-9_*.]+)/gi, "");
}
 
export { categorise, tokenise, extractTableReference, cleanUnquotedIdentifier };