2

Starting with an apology that being a beginner in Scala, I could not find better wordings for the question.

I have a properties file where I need to define a few parameterized commands (or sql queries). Following is an example of this:

[section abc]
stage: StageA
query: Select count(*) FROM tableA WHERE account_id=${account_id} AND dt=$dt AND source=$source

[section def]
stage: StageB
query: Select count(*) FROM tableB WHERE event_date=${event_date} AND template=$template

In my code, I have a config object (consider a Map) which has the values for the variables in my query string (account_id, source, dt, event_date, template, etc.,). After reading the properties file I need to substitute all the macros in my query string. For this I want to write a single function with a signature like:

def resolve_query(query: String, config: Map[String, Any]): String

which should return the query text with the macros substituted with values from the config. I tried writing my own String Interpolator, but it didn't work. Is there anything else that I can try?

3
  • Are you sure you're not looking for a parametrized prepared statement in jdbc? Commented Jul 19, 2019 at 5:52
  • @KrzysztofAtłasik. thank you. Honestly, this is exactly what I want to build. Instead of using a JDBC client, can I write a simple (or complex) function that does the variable substitution. Commented Jul 19, 2019 at 6:44
  • Or you can have a look at Anorm Commented Jul 19, 2019 at 10:09

1 Answer 1

2

With string interpolation, the compiler cuts up a String literal into its parts before sending them to be recombined via StringContext. The compiler won't do that to a string value in a variable so you have to do the cutting yourself.

def resolve_query(query: String, config: Map[String, Any]): String =
  "(.*)\\$\\{([^}]+)}(.*)".r
    .findFirstMatchIn(query)
    .fold(query){ m =>
      resolve_query(StringContext(m.group(1)
                                 ,m.group(3)
                                 ).s(config.getOrElse(m.group(2), "unknown")
                                    )
                   ,config
                   )
                }

testing:

resolve_query(
  "Select count(*) FROM tableA WHERE account_id=${account_id} AND source=${source}"
 ,Map("account_id" -> 47, "source" -> "UK")
             )
//res0: String = Select count(*) FROM tableA WHERE account_id=47 AND source=UK

You'll note that I've only implemented the easier ${braces} delimited form. The $dollar delimited form isn't much trickier but allowing for both (either/or) would be more work than I'm willing to put in to it for now.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.