All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lucidchart.open.relate.SqlStatementParser.scala Maven / Gradle / Ivy

The newest version!
package com.lucidchart.open.relate

import scala.collection.mutable
import scala.collection.Map

private[relate] object SqlStatementParser {

  /**
   * Parse a SQL statement into parameters and replace all parameters with ?
   * @param stmt the statement to process
   * @param listParams a mapping of list parameter names to their sizes
   * @return a tuple containing the revised SQL statement and the parameter names to their index
   */
  def parse(stmt: String, listParams: Map[String, ListParam] = Map[String, ListParam]()):
    (String, Map[String, List[Int]]) = {
    
    val query = new StringBuilder(stmt.length + listParams.values.foldLeft(0) (_ + _.charCount))
    val param = new StringBuilder(100)
    
    var inParam = false
    val params = mutable.Map[String, List[Int]]()
    var index = 1
    var i = 0
    val chars = stmt.toCharArray
    while (i < chars.size) {
      val c = chars(i)
      if (!inParam) {
        if (c == '{') {
          if (i + 1 < chars.size && chars(i + 1) == '{') {
            i += 1
            query.append(c)
          }
          else {
            inParam = true
          }
        }
        else if (c == '}' && i + 1 < chars.size && chars(i + 1) == '}') {
          i += 1
          query.append(c)
        }
        else {
          query.append(c)
        }
      }
      else {
        if (c == '}') {
          val name = param.toString

          params(name) = if (params contains name) params(name) :+ index else List(index)
          if (!listParams.isEmpty && listParams.contains(name)) {
            listParams(name) match {
              case x: CommaSeparated => {
                insertCommaSeparated(x.count, query)
                index += x.count
              }
              case x: Tupled => {
                insertTuples(x.numTuples, x.tupleSize, query)
                index += x.count
              }
            }
          }
          else {
            query.append('?')
            index += 1
          }
          
          inParam = false
          param.clear
        }
        else {
          param.append(c)
        }
      }

      i += 1
    }

    (query.toString, params.toMap)
  }

  /**
   * Insert a comma separated list of comma separated ? into the query
   * @param count the number of parameters in the list
   * @param query the current query in a StringBuilder
   */
  private def insertCommaSeparated(count: Int, query: StringBuilder): Unit = {
    Iterator.fill(count)("?").addString(query, ",")
  }

  /**
   * Insert a comma separated list of tuples into the query
   * @param numTuples the number of tuples to insert
   * @param tupleSize the size of each tuple
   * @param query the current query in a StringBuilder
   */
  private def insertTuples(numTuples: Int, tupleSize: Int, query: StringBuilder): Unit = {
    for (i <- 0 to numTuples - 1) {
      if (i > 0) query append ','
      insertTuple(tupleSize, query)
    }
  }

  /**
   * Insert a single tuple into the query
   * @param tupleSize the size of the tuple
   * @param query the current query in a StringBuilder
   */
  private def insertTuple(tupleSize: Int, query: StringBuilder): Unit = {
    Iterator.fill(tupleSize)("?").addString(query, "(", ",", ")")
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy