Skip to content

Commit 88b884e

Browse files
committed
Add the EXTRACT expression (thanks to Andrey Karepin). Fixes patch #4
git-svn-id: https://svn.code.sf.net/p/openhms/code/sqlbuilder/trunk@546 f9ba57bc-9804-47c6-9de9-2f2ff8aac994
1 parent cf55b35 commit 88b884e

File tree

7 files changed

+261
-1
lines changed

7 files changed

+261
-1
lines changed

src/changes/changes.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
<author email="jahlborn@users.sf.net">James Ahlborn</author>
55
</properties>
66
<body>
7+
<release version="2.1.7" date="TBD">
8+
<action dev="jahlborn" type="add" system="SourceForge2Patches" issue="4">
9+
Add the EXTRACT expression (thanks to Andrey Karepin).
10+
</action>
11+
</release>
712
<release version="2.1.6" date="2016-12-18">
813
<action dev="jahlborn" type="update" system="SourceForge2Features" issue="19">
914
Add the BETWEEN condition.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
Copyright (c) 2017 Andrey Karepin
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package com.healthmarketscience.sqlbuilder;
18+
19+
import java.io.IOException;
20+
import com.healthmarketscience.common.util.AppendableExt;
21+
22+
23+
/**
24+
* Outputs an extract expression like:
25+
* <code>"EXTRACT(&lt;datePart&gt; FROM &lt;dateExpression&gt;)"</code>
26+
*
27+
* @see "SQL 2003"
28+
* @author Andrey Karepin
29+
*/
30+
public class ExtractExpression extends Expression
31+
{
32+
/**
33+
* The SQL defined date parts for the extract expression. Many databases
34+
* have extensions to these choices which can be found in the relevant
35+
* extensions module.
36+
*
37+
* @see com.healthmarketscience.sqlbuilder.custom.postgresql.PgExtractDatePart
38+
* @see com.healthmarketscience.sqlbuilder.custom.mysql.MysExtractDatePart
39+
* @see com.healthmarketscience.sqlbuilder.custom.oracle.OraExtractDatePart
40+
*/
41+
public enum DatePart
42+
{
43+
YEAR,
44+
MONTH,
45+
DAY,
46+
HOUR,
47+
MINUTE,
48+
SECOND,
49+
TIMEZONE_HOUR,
50+
TIMEZONE_MINUTE;
51+
}
52+
53+
private final Object _datePart;
54+
private final SqlObject _dateExpression;
55+
56+
public ExtractExpression(DatePart datePart, Object dateExpression) {
57+
this((Object)datePart, dateExpression);
58+
}
59+
60+
public ExtractExpression(Object datePart, Object dateExpression) {
61+
_datePart = datePart;
62+
_dateExpression = Converter.toColumnSqlObject(dateExpression);
63+
}
64+
65+
@Override
66+
public boolean hasParens() { return false; }
67+
68+
@Override
69+
protected void collectSchemaObjects(ValidationContext vContext) {
70+
_dateExpression.collectSchemaObjects(vContext);
71+
}
72+
73+
@Override
74+
public void appendTo(AppendableExt app) throws IOException {
75+
app.append("EXTRACT(")
76+
.append(_datePart)
77+
.append(" FROM ")
78+
.append(_dateExpression)
79+
.append(")");
80+
}
81+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Copyright (c) 2017 James Ahlborn
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package com.healthmarketscience.sqlbuilder.custom.mysql;
18+
19+
/**
20+
* The MySQL defined date parts for the
21+
* {@link com.healthmarketscience.sqlbuilder.ExtractExpression}.
22+
*
23+
* @see "SQL 2003"
24+
* @author James Ahlborn
25+
*/
26+
public enum MysExtractDatePart
27+
{
28+
MICROSECOND,
29+
SECOND,
30+
MINUTE,
31+
HOUR,
32+
DAY,
33+
WEEK,
34+
MONTH,
35+
QUARTER,
36+
YEAR,
37+
SECOND_MICROSECOND,
38+
MINUTE_MICROSECOND,
39+
MINUTE_SECOND,
40+
HOUR_MICROSECOND,
41+
HOUR_SECOND,
42+
HOUR_MINUTE,
43+
DAY_MICROSECOND,
44+
DAY_SECOND,
45+
DAY_MINUTE,
46+
DAY_HOUR,
47+
YEAR_MONTH;
48+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
Copyright (c) 2017 James Ahlborn
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package com.healthmarketscience.sqlbuilder.custom.oracle;
18+
19+
/**
20+
* The Oracle defined date parts for the
21+
* {@link com.healthmarketscience.sqlbuilder.ExtractExpression}.
22+
*
23+
* @see "SQL 2003"
24+
* @author James Ahlborn
25+
*/
26+
public enum OraExtractDatePart
27+
{
28+
YEAR,
29+
MONTH,
30+
DAY,
31+
HOUR,
32+
MINUTE,
33+
SECOND,
34+
TIMEZONE_HOUR,
35+
TIMEZONE_MINUTE,
36+
TIMEZONE_REGION,
37+
TIMEZONE_ABBR;
38+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Copyright (c) 2017 Andrey Karepin
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package com.healthmarketscience.sqlbuilder.custom.postgresql;
18+
19+
/**
20+
* The PostgreSQL defined date parts for the
21+
* {@link com.healthmarketscience.sqlbuilder.ExtractExpression}.
22+
*
23+
* @see "SQL 2003"
24+
* @author Andrey Karepin
25+
*/
26+
public enum PgExtractDatePart
27+
{
28+
CENTURY,
29+
DAY,
30+
DECADE,
31+
DOW,
32+
DOY,
33+
EPOCH,
34+
HOUR,
35+
ISODOW,
36+
ISOYEAR,
37+
MICROSECONDS,
38+
MILLENNIUM,
39+
MILLISECONDS,
40+
MINUTE,
41+
MONTH,
42+
QUARTER,
43+
SECOND,
44+
TIMEZONE,
45+
TIMEZONE_HOUR,
46+
TIMEZONE_MINUTE,
47+
WEEK,
48+
YEAR;
49+
}

src/test/java/com/healthmarketscience/sqlbuilder/SqlBuilderTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,4 +1106,12 @@ public void testBetweenCondition()
11061106
"((t0.col1 < 'FOO') AND (t2.col4 BETWEEN 'this string' AND 37))");
11071107
}
11081108

1109+
public void testExtractExpression()
1110+
{
1111+
String exprStr = BinaryCondition.equalTo(
1112+
"2016",
1113+
new ExtractExpression(ExtractExpression.DatePart.YEAR, "2016-01-01"))
1114+
.toString();
1115+
checkResult(exprStr, "('2016' = EXTRACT(YEAR FROM '2016-01-01'))");
1116+
}
11091117
}

src/test/java/com/healthmarketscience/sqlbuilder/custom/CustomSyntaxTest.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,20 @@
2020
import com.healthmarketscience.sqlbuilder.BinaryCondition;
2121
import com.healthmarketscience.sqlbuilder.CreateIndexQuery;
2222
import com.healthmarketscience.sqlbuilder.CreateTableQuery;
23+
import com.healthmarketscience.sqlbuilder.ExtractExpression;
2324
import com.healthmarketscience.sqlbuilder.SelectQuery;
2425
import com.healthmarketscience.sqlbuilder.ValidationException;
26+
import com.healthmarketscience.sqlbuilder.custom.mysql.MysExtractDatePart;
2527
import com.healthmarketscience.sqlbuilder.custom.mysql.MysLimitClause;
2628
import com.healthmarketscience.sqlbuilder.custom.mysql.MysObjects;
29+
import com.healthmarketscience.sqlbuilder.custom.oracle.OraExtractDatePart;
2730
import com.healthmarketscience.sqlbuilder.custom.oracle.OraObjects;
2831
import com.healthmarketscience.sqlbuilder.custom.oracle.OraTableSpaceClause;
2932
import com.healthmarketscience.sqlbuilder.custom.postgresql.PgBinaryCondition;
33+
import com.healthmarketscience.sqlbuilder.custom.postgresql.PgExtractDatePart;
3034
import com.healthmarketscience.sqlbuilder.custom.postgresql.PgLimitClause;
31-
import com.healthmarketscience.sqlbuilder.custom.postgresql.PgOffsetClause;
3235
import com.healthmarketscience.sqlbuilder.custom.postgresql.PgObjects;
36+
import com.healthmarketscience.sqlbuilder.custom.postgresql.PgOffsetClause;
3337
import com.healthmarketscience.sqlbuilder.custom.sqlserver.MssTopClause;
3438
import com.healthmarketscience.sqlbuilder.dbspec.basic.DbIndex;
3539

@@ -103,6 +107,15 @@ public void testMysqlCreateTableClause()
103107
"CREATE TABLE IF NOT EXISTS Schema1.Table1 (col1 VARCHAR(213),col2 NUMBER(7),col3 DECIMAL(4,8) AUTO_INCREMENT,col4 VARCHAR(255))");
104108
}
105109

110+
public void testMysqlExtractExpression()
111+
{
112+
String exprStr = BinaryCondition.equalTo(
113+
"2016",
114+
new ExtractExpression(MysExtractDatePart.MICROSECOND, "2016-01-01"))
115+
.toString();
116+
checkResult(exprStr, "('2016' = EXTRACT(MICROSECOND FROM '2016-01-01'))");
117+
}
118+
106119
public void testPostgresqlLimitClause()
107120
{
108121
String selectQuery1 = new SelectQuery()
@@ -191,6 +204,15 @@ public void testPostgresqlBinaryCondition()
191204
"SELECT t0.col1 FROM Schema1.Table1 t0 WHERE (t0.col1 ILIKE 'foo%' ESCAPE '\\')");
192205
}
193206

207+
public void testPostgresqlExtractExpression()
208+
{
209+
String exprStr = BinaryCondition.equalTo(
210+
"2016",
211+
new ExtractExpression(PgExtractDatePart.CENTURY, "2016-01-01"))
212+
.toString();
213+
checkResult(exprStr, "('2016' = EXTRACT(CENTURY FROM '2016-01-01'))");
214+
}
215+
194216
public void testOracleTablespace()
195217
{
196218
String createTableStr = new CreateTableQuery(_table1, true)
@@ -218,6 +240,15 @@ public void testOracleLimitClause()
218240
"SELECT t0.col1 FROM Schema1.Table1 t0 WHERE (ROWNUM < 100)");
219241
}
220242

243+
public void testOracleExtractExpression()
244+
{
245+
String exprStr = BinaryCondition.equalTo(
246+
"2016",
247+
new ExtractExpression(OraExtractDatePart.TIMEZONE_ABBR, "2016-01-01"))
248+
.toString();
249+
checkResult(exprStr, "('2016' = EXTRACT(TIMEZONE_ABBR FROM '2016-01-01'))");
250+
}
251+
221252
public void testSQLServerTopClause()
222253
{
223254
String selectQuery1 = new SelectQuery()

0 commit comments

Comments
 (0)