From 18be5989c7d31f8df3507fcf9376862cdf1dea6f Mon Sep 17 00:00:00 2001 From: Antony Puckey Date: Tue, 29 Dec 2015 11:06:22 +1000 Subject: [PATCH] Added support for custom database functions that have multiple arguments seperated by commas inside brackets. --- .../com/avaje/ebean/DRawSqlColumnsParser.java | 10 +++-- .../avaje/ebean/TestRawSqlColumnParsing.java | 37 ++++++++++++++++++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/avaje/ebean/DRawSqlColumnsParser.java b/src/main/java/com/avaje/ebean/DRawSqlColumnsParser.java index 15902f7c8..08d4b94ca 100644 --- a/src/main/java/com/avaje/ebean/DRawSqlColumnsParser.java +++ b/src/main/java/com/avaje/ebean/DRawSqlColumnsParser.java @@ -45,7 +45,7 @@ final class DRawSqlColumnsParser { String colInfo = sqlSelect.substring(start, pos++); colInfo = colInfo.trim(); - String[] split = colInfo.split(" "); + String[] split = colInfo.split("\\s(?=[^\\)]*(?:\\(|$))"); if (split.length > 1) { ArrayList tmp = new ArrayList(split.length); for (int i = 0; i < split.length; i++) { @@ -82,11 +82,13 @@ final class DRawSqlColumnsParser { private void nextComma() { boolean inQuote = false; + int inbrackets = 0; while (pos < end) { char c = sqlSelect.charAt(pos); - if (c == '\'') { - inQuote = !inQuote; - } else if (!inQuote && c == ',') { + if (c == '\'') inQuote = !inQuote; + else if (c == '(') inbrackets++; + else if (c == ')') inbrackets--; + else if (!inQuote && inbrackets == 0 && c == ',') { return; } pos++; diff --git a/src/test/java/com/avaje/ebean/TestRawSqlColumnParsing.java b/src/test/java/com/avaje/ebean/TestRawSqlColumnParsing.java index d5bf79e0a..e297c71c2 100644 --- a/src/test/java/com/avaje/ebean/TestRawSqlColumnParsing.java +++ b/src/test/java/com/avaje/ebean/TestRawSqlColumnParsing.java @@ -89,7 +89,42 @@ public class TestRawSqlColumnParsing extends TestCase { } - + public void test_withDatabaseFunction() { + + ColumnMapping columnMapping = DRawSqlColumnsParser.parse("a a0,b b1, MONTH(MAKEDATE(2015, 241)) m2 , d d3 , e e4 "); + Map mapping = columnMapping.mapping(); + + assertEquals(5, mapping.size()); + + Column c = mapping.get("a"); + + assertEquals("a",c.getDbColumn()); + assertEquals(0, c.getIndexPos()); + assertEquals("a0",c.getPropertyName()); + + c = mapping.get("b"); + assertEquals("b",c.getDbColumn()); + assertEquals(1, c.getIndexPos()); + assertEquals("b1",c.getPropertyName()); + + c = mapping.get("MONTH(MAKEDATE(2015, 241))"); + assertEquals("MONTH(MAKEDATE(2015, 241))",c.getDbColumn()); + assertEquals(2, c.getIndexPos()); + assertEquals("m2",c.getPropertyName()); + + c = mapping.get("d"); + assertEquals("d",c.getDbColumn()); + assertEquals(3, c.getIndexPos()); + assertEquals("d3",c.getPropertyName()); + + + c = mapping.get("e"); + assertEquals("e",c.getDbColumn()); + assertEquals(4, c.getIndexPos()); + assertEquals("e4",c.getPropertyName()); + + } + public void test_withAsAlias() { ColumnMapping columnMapping = DRawSqlColumnsParser.parse("a as a0,'b' b1, \"c(blah)\" as c2 , d as d3 , e as e4 ");