diff --git a/pom.xml b/pom.xml index 6ef6eb5..e57297b 100644 --- a/pom.xml +++ b/pom.xml @@ -45,10 +45,13 @@ test - + + src/main/resources + + . LICENSE @@ -57,17 +60,35 @@ - org.apache.maven.plugins maven-compiler-plugin 3.8.0 - 1.8 - 1.8 + 17 + 17 true + + + default-compile + + -proc:none + + ua/net/uid/utils/db/orm/Processor.java + + + + + + compile-project + compile + + compile + + + @@ -124,8 +145,8 @@ UTF-8 - 1.8 - 1.8 + 17 + 17 uid-releases diff --git a/src/main/java/ua/net/uid/utils/db/annotation/Column.java b/src/main/java/ua/net/uid/utils/db/annotation/Column.java new file mode 100644 index 0000000..de4ff31 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/annotation/Column.java @@ -0,0 +1,38 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Specifies the mapped column for a persistent property or field. + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.SOURCE) +public @interface Column { + /** + * The name of the column.Defaults to the property or field name. + * @return + */ + String name() default ""; + + boolean autoincrement() default false; + + boolean nullable() default true; +} diff --git a/src/main/java/ua/net/uid/utils/db/annotation/Composite.java b/src/main/java/ua/net/uid/utils/db/annotation/Composite.java new file mode 100644 index 0000000..a1db483 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/annotation/Composite.java @@ -0,0 +1,26 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.SOURCE) +public @interface Composite { +} diff --git a/src/main/java/ua/net/uid/utils/db/annotation/Entity.java b/src/main/java/ua/net/uid/utils/db/annotation/Entity.java new file mode 100644 index 0000000..4f2b3ea --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/annotation/Entity.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Specifies that the class is an entity. + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Entity { + /** + * The name of the table.Defaults to the entity name. + * @return + */ + String name() default ""; + /** + * The schema of the table.Defaults to the default schema for user. + * @return + */ + String schema() default ""; +} diff --git a/src/main/java/ua/net/uid/utils/db/annotation/PrimaryKey.java b/src/main/java/ua/net/uid/utils/db/annotation/PrimaryKey.java new file mode 100644 index 0000000..5c3b06c --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/annotation/PrimaryKey.java @@ -0,0 +1,26 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.SOURCE) +public @interface PrimaryKey { +} diff --git a/src/main/java/ua/net/uid/utils/db/dao/DAO.java b/src/main/java/ua/net/uid/utils/db/dao/DAO.java deleted file mode 100644 index d938102..0000000 --- a/src/main/java/ua/net/uid/utils/db/dao/DAO.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 nightfall. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ua.net.uid.utils.db.dao; - -import ua.net.uid.utils.db.Session; - -public interface DAO { - Session getSession(); -} diff --git a/src/main/java/ua/net/uid/utils/db/dao/DAOAbstract.java b/src/main/java/ua/net/uid/utils/db/dao/DAOAbstract.java deleted file mode 100644 index e171851..0000000 --- a/src/main/java/ua/net/uid/utils/db/dao/DAOAbstract.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2020 nightfall. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ua.net.uid.utils.db.dao; - -import ua.net.uid.utils.db.Session; - -import java.io.Serializable; - -public abstract class DAOAbstract, PK extends Serializable> extends DAOCore implements DAOBase { - public DAOAbstract(Session session) { - super(session); - } -} diff --git a/src/main/java/ua/net/uid/utils/db/dao/DAOBase.java b/src/main/java/ua/net/uid/utils/db/dao/DAOBase.java deleted file mode 100644 index 9ec7f02..0000000 --- a/src/main/java/ua/net/uid/utils/db/dao/DAOBase.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2020 nightfall. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ua.net.uid.utils.db.dao; - -import ua.net.uid.utils.db.Fetcher; -import ua.net.uid.utils.db.Outcome; -import ua.net.uid.utils.db.query.Condition; -import ua.net.uid.utils.db.query.Order; -import ua.net.uid.utils.db.query.QueryBuilder; - -import java.io.Serializable; -import java.sql.SQLException; -import java.util.List; -import ua.net.uid.utils.db.Processor; - -public interface DAOBase, PK extends Serializable> extends DAO { - String getTableName(); - - Condition getPrimaryCondition(PK key); - - default Order getDefaultOrder() { - return null; - } - - Fetcher getFetcher(); - - default T get(PK key) throws SQLException { - return getBy(getPrimaryCondition(key)); - } - - default T getBy(Condition condition) throws SQLException { - return new QueryBuilder() - .append("SELECT * FROM ").append(getTableName()) - .append(" WHERE ", condition) - .append(" LIMIT 1") - .on(getSession()).scalar(getFetcher()); - } - - default long countAll() throws SQLException { - return getSession().query("SELECT COUNT(*) FROM " + getTableName()).select(Outcome.FIRST_LONG); - } - - default List findAll() throws SQLException { - return findAll(getDefaultOrder()); - } - - default void foreachAll(Processor.Callback callback) throws SQLException { - foreachAll(callback, getDefaultOrder()); - } - - default List findAll(Order order) throws SQLException { - return new QueryBuilder().append("SELECT * FROM ").append(getTableName()) - .append(order).on(getSession()).list(getFetcher()); - } - - default void foreachAll(Processor.Callback callback, Order order) throws SQLException { - new QueryBuilder() - .append("SELECT * FROM ").append(getTableName()) - .append(order) - .on(getSession()).foreach(getFetcher(), callback); - } - - default List findAll(long limit, long offset) throws SQLException { - return findAll(getDefaultOrder(), limit, offset); - } - - default void foreachAll(Processor.Callback callback, long limit, long offset) throws SQLException { - foreachAll(callback, getDefaultOrder(), limit, offset); - } - - default List findAll(Order order, long limit, long offset) throws SQLException { - return new QueryBuilder().append("SELECT * FROM ").append(getTableName()) - .append(order).on(getSession()).list(getFetcher()); - } - - default void foreachAll(Processor.Callback callback, Order order, long limit, long offset) throws SQLException { - new QueryBuilder() - .append("SELECT * FROM ").append(getTableName()) - .append(order) - .append(" LIMIT ? OFFSET ?", limit, offset) - .on(getSession()).foreach(getFetcher(), callback); - } - - default long countBy(Condition condition) throws SQLException { - return new QueryBuilder() - .append("SELECT COUNT(*) FROM ") - .append(getTableName()) - .append(" WHERE ", condition) - .on(getSession()).select(Outcome.FIRST_LONG); - } - - default List findBy(Condition condition) throws SQLException { - return findBy(condition, getDefaultOrder()); - } - - default void foreachBy(Processor.Callback callback, Condition condition) throws SQLException { - foreachBy(callback, condition, getDefaultOrder()); - } - - default List findBy(Condition condition, Order order) throws SQLException { - return new QueryBuilder() - .append("SELECT * FROM ").append(getTableName()) - .append(" WHERE ", condition) - .append(order) - .on(getSession()).list(getFetcher()); - } - - default void foreachBy(Processor.Callback callback, Condition condition, Order order) throws SQLException { - new QueryBuilder() - .append("SELECT * FROM ").append(getTableName()) - .append(" WHERE ", condition) - .append(order) - .on(getSession()).foreach(getFetcher(), callback); - } - - default List findBy(Condition condition, long limit, long offset) throws SQLException { - return findBy(condition, getDefaultOrder(), limit, offset); - } - - default void foreachBy(Processor.Callback callback, Condition condition, long limit, long offset) throws SQLException { - foreachBy(callback, condition, getDefaultOrder(), limit, offset); - } - - default List findBy(Condition condition, Order order, long limit, long offset) throws SQLException { - return new QueryBuilder() - .append("SELECT * FROM ").append(getTableName()) - .append(" WHERE ", condition) - .append(" LIMIT ? OFFSET ?", limit, offset) - .append(order) - .on(getSession()).list(getFetcher()); - } - - default void foreachBy(Processor.Callback callback, Condition condition, Order order, long limit, long offset) throws SQLException { - new QueryBuilder() - .append("SELECT * FROM ").append(getTableName()) - .append(" WHERE ", condition) - .append(" LIMIT ? OFFSET ?", limit, offset) - .append(order) - .on(getSession()).foreach(getFetcher(), callback); - } - - boolean insert(T item) throws SQLException; - - boolean update(T item, PK key) throws SQLException; - - default boolean update(T item) throws SQLException { - return update(item, item.getPrimaryKey()); - } - - default boolean delete(PK key) throws SQLException { - return new QueryBuilder() - .append("DELETE FROM ").append(getTableName()) - .append(" WHERE ", getPrimaryCondition(key)) - .on(getSession()).update() > 0; - } - - default boolean delete(T item) throws SQLException { - return delete(item.getPrimaryKey()); - } -} diff --git a/src/main/java/ua/net/uid/utils/db/dao/DAOCore.java b/src/main/java/ua/net/uid/utils/db/dao/DAOCore.java deleted file mode 100644 index 90e84b7..0000000 --- a/src/main/java/ua/net/uid/utils/db/dao/DAOCore.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2020 nightfall. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ua.net.uid.utils.db.dao; - -import ua.net.uid.utils.db.Session; - -public abstract class DAOCore implements DAO { - private final Session session; - - public DAOCore(Session session) { - this.session = session; - } - - @Override - public Session getSession() { - return session; - } -} diff --git a/src/main/java/ua/net/uid/utils/db/dao/DAOInterface.java b/src/main/java/ua/net/uid/utils/db/dao/DAOInterface.java new file mode 100644 index 0000000..4322ee3 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/dao/DAOInterface.java @@ -0,0 +1,23 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.dao; + +import java.io.Serializable; + +public interface DAOInterface extends DAOReaderInterface, DAOWriterInterface +{ + +} diff --git a/src/main/java/ua/net/uid/utils/db/dao/DAOReaderInterface.java b/src/main/java/ua/net/uid/utils/db/dao/DAOReaderInterface.java new file mode 100644 index 0000000..86a0359 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/dao/DAOReaderInterface.java @@ -0,0 +1,23 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.dao; + +import java.io.Serializable; + +public interface DAOReaderInterface extends SessionObjectInterface { + + +} diff --git a/src/main/java/ua/net/uid/utils/db/dao/DAOWriterInterface.java b/src/main/java/ua/net/uid/utils/db/dao/DAOWriterInterface.java new file mode 100644 index 0000000..891df30 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/dao/DAOWriterInterface.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.dao; + +import java.io.Serializable; +import java.sql.SQLException; + +public interface DAOWriterInterface extends SessionObjectInterface { + boolean insert(T item) throws SQLException; + boolean update(T item, PK key) throws SQLException; + boolean update(T item) throws SQLException; + boolean delete(PK key) throws SQLException; + boolean delete(T item) throws SQLException; +} diff --git a/src/main/java/ua/net/uid/utils/db/dao/Entity.java b/src/main/java/ua/net/uid/utils/db/dao/Entity.java deleted file mode 100644 index c1eec12..0000000 --- a/src/main/java/ua/net/uid/utils/db/dao/Entity.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 nightfall. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ua.net.uid.utils.db.dao; - -import java.io.Serializable; - -public interface Entity { - PK getPrimaryKey(); -} diff --git a/src/main/java/ua/net/uid/utils/db/dao/EntityInterface.java b/src/main/java/ua/net/uid/utils/db/dao/EntityInterface.java new file mode 100644 index 0000000..8596660 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/dao/EntityInterface.java @@ -0,0 +1,22 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.dao; + +import java.io.Serializable; + +public interface EntityInterface { + public PK primaryKey(); +} diff --git a/src/main/java/ua/net/uid/utils/db/dao/SessionObject.java b/src/main/java/ua/net/uid/utils/db/dao/SessionObject.java new file mode 100644 index 0000000..df1dc16 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/dao/SessionObject.java @@ -0,0 +1,31 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.dao; + +import ua.net.uid.utils.db.Session; + +public class SessionObject implements SessionObjectInterface { + private final Session session; + + public SessionObject(Session session) { + this.session = session; + } + + @Override + public Session getSession() { + return session; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/dao/SessionObjectInterface.java b/src/main/java/ua/net/uid/utils/db/dao/SessionObjectInterface.java new file mode 100644 index 0000000..f12e800 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/dao/SessionObjectInterface.java @@ -0,0 +1,22 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.dao; + +import ua.net.uid.utils.db.Session; + +public interface SessionObjectInterface { + Session getSession(); +} diff --git a/src/main/java/ua/net/uid/utils/db/old/annotation/Column.java b/src/main/java/ua/net/uid/utils/db/old/annotation/Column.java new file mode 100644 index 0000000..867d68b --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/annotation/Column.java @@ -0,0 +1,34 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Specifies the mapped column for a persistent property or field. + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.FIELD) +public @interface Column { + /** + * The name of the column. + */ + String name() default ""; + //boolean auto() default false; +} diff --git a/src/main/java/ua/net/uid/utils/db/old/annotation/Columns.java b/src/main/java/ua/net/uid/utils/db/old/annotation/Columns.java new file mode 100644 index 0000000..a98c188 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/annotation/Columns.java @@ -0,0 +1,26 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.FIELD) +public @interface Columns { +} diff --git a/src/main/java/ua/net/uid/utils/db/old/annotation/Entity.java b/src/main/java/ua/net/uid/utils/db/old/annotation/Entity.java new file mode 100644 index 0000000..16788c5 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/annotation/Entity.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.FIELD) +public @interface Entity { + String name() default ""; +} diff --git a/src/main/java/ua/net/uid/utils/db/old/annotation/PrimaryKey.java b/src/main/java/ua/net/uid/utils/db/old/annotation/PrimaryKey.java new file mode 100644 index 0000000..1f49aea --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/annotation/PrimaryKey.java @@ -0,0 +1,26 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.FIELD) +public @interface PrimaryKey { +} \ No newline at end of file diff --git a/src/main/java/ua/net/uid/utils/db/old/annotation/Select.java b/src/main/java/ua/net/uid/utils/db/old/annotation/Select.java new file mode 100644 index 0000000..cf3750c --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/annotation/Select.java @@ -0,0 +1,29 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import ua.net.uid.utils.db.Fetcher; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.METHOD) +public @interface Select { + String sql(); + Class fetcher() default Fetcher.class; +} diff --git a/src/main/java/ua/net/uid/utils/db/old/annotation/Table.java b/src/main/java/ua/net/uid/utils/db/old/annotation/Table.java new file mode 100644 index 0000000..4adfa26 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/annotation/Table.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Table { + String value(); +} diff --git a/src/main/java/ua/net/uid/utils/db/old/annotation/Update.java b/src/main/java/ua/net/uid/utils/db/old/annotation/Update.java new file mode 100644 index 0000000..024f6d0 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/annotation/Update.java @@ -0,0 +1,28 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.METHOD) +public @interface Update { + String sql(); + boolean returnAuto() default false; +} diff --git a/src/main/java/ua/net/uid/utils/db/old/dao/DAO.java b/src/main/java/ua/net/uid/utils/db/old/dao/DAO.java new file mode 100644 index 0000000..317c69f --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/dao/DAO.java @@ -0,0 +1,22 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.dao; + +import ua.net.uid.utils.db.Session; + +public interface DAO { + Session getSession(); +} diff --git a/src/main/java/ua/net/uid/utils/db/old/dao/DAOAbstract.java b/src/main/java/ua/net/uid/utils/db/old/dao/DAOAbstract.java new file mode 100644 index 0000000..7814f71 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/dao/DAOAbstract.java @@ -0,0 +1,26 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.dao; + +import ua.net.uid.utils.db.Session; + +import java.io.Serializable; + +public abstract class DAOAbstract, PK extends Serializable> extends DAOCore implements DAOBase { + public DAOAbstract(Session session) { + super(session); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/old/dao/DAOBase.java b/src/main/java/ua/net/uid/utils/db/old/dao/DAOBase.java new file mode 100644 index 0000000..a06b53c --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/dao/DAOBase.java @@ -0,0 +1,173 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.dao; + +import ua.net.uid.utils.db.Fetcher; +import ua.net.uid.utils.db.Outcome; +import ua.net.uid.utils.db.old.query.Condition; +import ua.net.uid.utils.db.old.query.Order; +import ua.net.uid.utils.db.old.query.QueryBuilder; + +import java.io.Serializable; +import java.sql.SQLException; +import java.util.List; +import ua.net.uid.utils.db.Processor; + +public interface DAOBase, PK extends Serializable> extends DAO { + String getTableName(); + + Condition getPrimaryCondition(PK key); + + default Order getDefaultOrder() { + return null; + } + + Fetcher getFetcher(); + + default T get(PK key) throws SQLException { + return getBy(getPrimaryCondition(key)); + } + + default T getBy(Condition condition) throws SQLException { + return new QueryBuilder() + .append("SELECT * FROM ").append(getTableName()) + .append(" WHERE ", condition) + .append(" LIMIT 1") + .on(getSession()).scalar(getFetcher()); + } + + default long countAll() throws SQLException { + return getSession().query("SELECT COUNT(*) FROM " + getTableName()).select(Outcome.FIRST_LONG); + } + + default List findAll() throws SQLException { + return findAll(getDefaultOrder()); + } + + default void foreachAll(Processor.Callback callback) throws SQLException { + foreachAll(callback, getDefaultOrder()); + } + + default List findAll(Order order) throws SQLException { + return new QueryBuilder().append("SELECT * FROM ").append(getTableName()) + .append(order).on(getSession()).list(getFetcher()); + } + + default void foreachAll(Processor.Callback callback, Order order) throws SQLException { + new QueryBuilder() + .append("SELECT * FROM ").append(getTableName()) + .append(order) + .on(getSession()).foreach(getFetcher(), callback); + } + + default List findAll(long limit, long offset) throws SQLException { + return findAll(getDefaultOrder(), limit, offset); + } + + default void foreachAll(Processor.Callback callback, long limit, long offset) throws SQLException { + foreachAll(callback, getDefaultOrder(), limit, offset); + } + + default List findAll(Order order, long limit, long offset) throws SQLException { + return new QueryBuilder().append("SELECT * FROM ").append(getTableName()) + .append(order).on(getSession()).list(getFetcher()); + } + + default void foreachAll(Processor.Callback callback, Order order, long limit, long offset) throws SQLException { + new QueryBuilder() + .append("SELECT * FROM ").append(getTableName()) + .append(order) + .append(" LIMIT ? OFFSET ?", limit, offset) + .on(getSession()).foreach(getFetcher(), callback); + } + + default long countBy(Condition condition) throws SQLException { + return new QueryBuilder() + .append("SELECT COUNT(*) FROM ") + .append(getTableName()) + .append(" WHERE ", condition) + .on(getSession()).select(Outcome.FIRST_LONG); + } + + default List findBy(Condition condition) throws SQLException { + return findBy(condition, getDefaultOrder()); + } + + default void foreachBy(Processor.Callback callback, Condition condition) throws SQLException { + foreachBy(callback, condition, getDefaultOrder()); + } + + default List findBy(Condition condition, Order order) throws SQLException { + return new QueryBuilder() + .append("SELECT * FROM ").append(getTableName()) + .append(" WHERE ", condition) + .append(order) + .on(getSession()).list(getFetcher()); + } + + default void foreachBy(Processor.Callback callback, Condition condition, Order order) throws SQLException { + new QueryBuilder() + .append("SELECT * FROM ").append(getTableName()) + .append(" WHERE ", condition) + .append(order) + .on(getSession()).foreach(getFetcher(), callback); + } + + default List findBy(Condition condition, long limit, long offset) throws SQLException { + return findBy(condition, getDefaultOrder(), limit, offset); + } + + default void foreachBy(Processor.Callback callback, Condition condition, long limit, long offset) throws SQLException { + foreachBy(callback, condition, getDefaultOrder(), limit, offset); + } + + default List findBy(Condition condition, Order order, long limit, long offset) throws SQLException { + return new QueryBuilder() + .append("SELECT * FROM ").append(getTableName()) + .append(" WHERE ", condition) + .append(" LIMIT ? OFFSET ?", limit, offset) + .append(order) + .on(getSession()).list(getFetcher()); + } + + default void foreachBy(Processor.Callback callback, Condition condition, Order order, long limit, long offset) throws SQLException { + new QueryBuilder() + .append("SELECT * FROM ").append(getTableName()) + .append(" WHERE ", condition) + .append(" LIMIT ? OFFSET ?", limit, offset) + .append(order) + .on(getSession()).foreach(getFetcher(), callback); + } + + boolean insert(T item) throws SQLException; + + boolean update(T item, PK key) throws SQLException; + + default boolean update(T item) throws SQLException { + return update(item, item.getPrimaryKey()); + } + + default boolean delete(PK key) throws SQLException { + return new QueryBuilder() + .append("DELETE FROM ").append(getTableName()) + .append(" WHERE ", getPrimaryCondition(key)) + .on(getSession()).update() > 0; + } + + default boolean delete(T item) throws SQLException { + return delete(item.getPrimaryKey()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/old/dao/DAOCore.java b/src/main/java/ua/net/uid/utils/db/old/dao/DAOCore.java new file mode 100644 index 0000000..610f95c --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/dao/DAOCore.java @@ -0,0 +1,31 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.dao; + +import ua.net.uid.utils.db.Session; + +public abstract class DAOCore implements DAO { + private final Session session; + + public DAOCore(Session session) { + this.session = session; + } + + @Override + public Session getSession() { + return session; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/old/dao/Entity.java b/src/main/java/ua/net/uid/utils/db/old/dao/Entity.java new file mode 100644 index 0000000..517a0cd --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/dao/Entity.java @@ -0,0 +1,22 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.dao; + +import java.io.Serializable; + +public interface Entity { + PK getPrimaryKey(); +} diff --git a/src/main/java/ua/net/uid/utils/db/old/orm/EntityColumn.java b/src/main/java/ua/net/uid/utils/db/old/orm/EntityColumn.java new file mode 100644 index 0000000..d52d151 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/orm/EntityColumn.java @@ -0,0 +1,132 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.orm; + +import ua.net.uid.utils.db.orm.Utils; +import java.io.IOException; +import java.util.Date; +import java.util.TimeZone; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.ArrayType; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import ua.net.uid.utils.db.old.annotation.Column; +import ua.net.uid.utils.db.old.annotation.PrimaryKey; + +public class EntityColumn extends EntityField { + + private final String name; + private final boolean primary; + + public EntityColumn(VariableElement variableElement, EntityField parentField) { + super(variableElement, parentField); + Column column = variableElement.getAnnotation(Column.class); + name = "".equals(column.name()) ? variableElement.getSimpleName().toString() : column.name(); + primary = variableElement.getAnnotation(PrimaryKey.class) != null; + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean hasPrimary() { + return primary; + } + + @Override + public boolean isPrimaryKey() { + return primary; + } + + @Override + public EntityField getPrimaryKey() { + return primary ? this : null; + } + + @Override + public void writeFetch(Appendable builder, String item) throws IOException { + builder.append(" ").append(item).append('.'); + final boolean dirrect = !writeSetter(builder); + builder.append(dirrect ? " = " : "("); + final TypeMirror typeMirror = getVariableElement().asType(); + switch (typeMirror.getKind()) { + case ARRAY: + final TypeMirror componentType = ((ArrayType) typeMirror).getComponentType(); + if (componentType.getKind() == TypeKind.BYTE) { + builder.append("result.getBytes(\"").append(name).append("\")"); + } else { + builder.append("result.getArray(\"").append(name).append("\").getArray()"); + } + break; + case DECLARED: + final TypeElement typeElement = (TypeElement) ((DeclaredType) typeMirror).asElement(); + if (Utils.isAssignableFrom(typeElement, TimeZone.class)) { + builder.append("java.util.TimeZone.getTimeZone(result.getString(\"").append(name).append("\"))"); + } else if (Utils.isAssignableFrom(typeElement, Date.class)) { + builder.append("result.getTimestamp(\"").append(name).append("\")"); + } else if (Utils.isAssignableFrom(typeElement, String.class)) { + builder.append("result.getString(\"").append(name).append("\")"); + } else if (typeElement.getKind() == ElementKind.ENUM) { + builder.append(typeElement.getQualifiedName()).append(".valueOf(result.getString(\"").append(name).append("\"))"); + } else { + builder.append('(').append(typeElement.getQualifiedName()).append(")result.getObject(\"").append(name).append("\")"); + } + break; + default: + switch (typeMirror.getKind()) { + case BOOLEAN: + builder.append("result.getBoolean(\"").append(name).append("\")"); + break; + case BYTE: + builder.append("result.getByte(\"").append(name).append("\")"); + break; + case CHAR: + builder.append("result.getString(\"").append(name).append("\").charAt(0)"); + break; + case SHORT: + builder.append("result.getShort(\"").append(name).append("\")"); + break; + case INT: + builder.append("result.getInt(\"").append(name).append("\")"); + break; + case LONG: + builder.append("result.getLong(\"").append(name).append("\")"); + break; + case FLOAT: + builder.append("result.getFloat(\"").append(name).append("\")"); + break; + case DOUBLE: + builder.append("result.getDouble(\"").append(name).append("\")"); + break; + default: + builder.append("result.getObject(\"").append(name).append("\")"); + break; + } + break; + } + builder.append(dirrect ? ";\n" : ");\n"); + } + + @Override + public void writeColums(Appendable builder, String postfix, String div) throws IOException { + builder.append('"').append(name).append('"').append(postfix); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/old/orm/EntityField.java b/src/main/java/ua/net/uid/utils/db/old/orm/EntityField.java new file mode 100644 index 0000000..4380176 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/orm/EntityField.java @@ -0,0 +1,59 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.orm; + + +import ua.net.uid.utils.db.orm.Utils; +import java.io.IOException; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; + +public abstract class EntityField { + private final EntityField parentField; + private final VariableElement variableElement; + + public EntityField(VariableElement variableElement, EntityField parentField) { + this.parentField = parentField; + this.variableElement = variableElement; + } + public EntityField getParent() { return parentField; } + public VariableElement getVariableElement() { return variableElement; } + public String getName() { return variableElement.toString(); } + + public abstract boolean hasPrimary(); + public abstract boolean isPrimaryKey(); + public abstract EntityField getPrimaryKey(); + + public abstract void writeFetch(Appendable builder, String item) throws IOException; + + public boolean writeSetter(Appendable builder) throws IOException { + final TypeElement typeElement = (TypeElement) variableElement.getEnclosingElement(); + final ExecutableElement setterElement = Utils.findSetter(getName(), typeElement); + if (setterElement != null) { + builder.append(setterElement.getSimpleName().toString()); + return true; + } else if (!variableElement.getModifiers().contains(Modifier.PRIVATE)) { + builder.append(variableElement.toString()); + return false; + } else { + throw new IOException("can`t find setter for " + variableElement.toString()); + } + } + + public abstract void writeColums(Appendable builder, String postfix, String div) throws IOException; +} diff --git a/src/main/java/ua/net/uid/utils/db/old/orm/EntityMeta.java b/src/main/java/ua/net/uid/utils/db/old/orm/EntityMeta.java new file mode 100644 index 0000000..8df9c80 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/orm/EntityMeta.java @@ -0,0 +1,139 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.orm; + +import ua.net.uid.utils.db.orm.Utils; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.processing.Filer; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.tools.JavaFileObject; +import ua.net.uid.utils.db.old.annotation.Column; +import ua.net.uid.utils.db.old.annotation.Columns; +import ua.net.uid.utils.db.old.annotation.PrimaryKey; +import ua.net.uid.utils.db.old.annotation.Table; + +public class EntityMeta { + private final Processor processor; + private final TypeElement typeElement; + private final PackageElement packageElement; + private final String tableName; + private final Map columns = new LinkedHashMap<>(); + private final List fields = new ArrayList<>(); + private final EntityField primaryField; + //private final EntityColumn auto; + private final String fetcherSimpleName; + private final String fetcherQualifiedName; + private final boolean fetcherFromResulSet; + + public EntityMeta(Processor processor, TypeElement typeElement) { + this.processor = processor; + this.typeElement = typeElement; + packageElement = Utils.getPackageElement(typeElement); + + final Table table = typeElement.getAnnotation(Table.class); + tableName = table == null ? typeElement.getSimpleName().toString() : table.value(); + + boolean simple = false; + EntityField primary = null; + for (Element element : typeElement.getEnclosedElements()) { + if (element.getKind() == ElementKind.CONSTRUCTOR) { + final ExecutableElement executable = (ExecutableElement) element; + if (executable.getParameters().size() == 1 && Utils.RESULTSET_CLASS.equals(executable.getParameters().get(0).asType().toString())) { + simple = true; + } + } else if (element.getKind() == ElementKind.FIELD) { + final VariableElement variable = (VariableElement) element; + EntityField field = null; + if (variable.getAnnotation(Column.class) != null) { + field = new EntityColumn(variable, null); + columns.put(field.getName(), (EntityColumn) field); + } else if (variable.getAnnotation(PrimaryKey.class) != null || variable.getAnnotation(Columns.class) != null) { + field = new EntityObject(variable, columns, null); + } + if (field != null) { + fields.add(field); + if (field.hasPrimary()) primary = field.getPrimaryKey(); + //if (_auto == null && field.isAuto()) _auto = field.getAuto(); + } + } + } + primaryField = primary; + fetcherSimpleName = typeElement.getQualifiedName().toString() + .substring(packageElement.getQualifiedName().length() + 1) + .replace('.', '_') + Utils.FETCHER_SUFFIX; + fetcherQualifiedName = packageElement.getQualifiedName() + "." + fetcherSimpleName; + System.err.println("\t" + fetcherQualifiedName); + fetcherFromResulSet = simple; + } + + public Processor getProcessor() { return processor; } + public TypeElement getTypeElement() { return typeElement; } + public PackageElement getPackageElement() { return packageElement; } + public String getTableName() { return tableName; } + public String getFetcherSimpleName() { return fetcherSimpleName; } + public String getFetcherQualifiedName() { return fetcherQualifiedName; } + public EntityField getPrimaryKey() { return primaryField; } + + public void generateFetcher(Filer filer) throws IOException { + JavaFileObject fileObject = filer.createSourceFile(fetcherQualifiedName, packageElement, typeElement); + try (final Writer writer = fileObject.openWriter()) { + final BufferedWriter builder = new BufferedWriter(writer); + writeFetcher(builder); + builder.flush(); + } + } + + private void writeFetcher(Appendable builder) throws IOException { + String simpleName = typeElement.getSimpleName().toString(); + builder.append("package ").append(packageElement.getQualifiedName()) + .append(";\npublic class ").append(fetcherSimpleName) + .append(" implements ").append(Utils.FETCHER_CLASS) + .append('<').append(simpleName).append("> {\n @Override\n public ") + .append(simpleName).append(" fetch(final ").append(Utils.RESULTSET_CLASS) + .append(" result) throws ").append(Utils.SQLEXCEPTION_CLASS).append(" {\n"); + if (fetcherFromResulSet) { + builder.append(" return new ").append(simpleName).append("(result);\n"); + } else { + builder.append(" ").append(simpleName).append(" item = new ").append(simpleName).append("();\n"); + for (EntityField field : fields) { + field.writeFetch(builder, "item"); + } + builder.append(" return item;\n"); + } + builder.append(" }\n public static ").append(fetcherSimpleName) + .append(" getInstance() { return Holder.INSTANCE; }\n private ") + .append(fetcherSimpleName) + .append("() {}\n private static class Holder {\n private static final ") + .append(fetcherSimpleName) + .append(" INSTANCE = new ").append(fetcherSimpleName).append("();\n }\n}\n"); + } + + /*public void writeDelete(Appendable builder, String param) throws IOException { + builder.append("\"DELETE FROM \\\"").append(tableName). + }*/ + +} diff --git a/src/main/java/ua/net/uid/utils/db/old/orm/EntityObject.java b/src/main/java/ua/net/uid/utils/db/old/orm/EntityObject.java new file mode 100644 index 0000000..803e820 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/orm/EntityObject.java @@ -0,0 +1,97 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.orm; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import ua.net.uid.utils.db.old.annotation.Column; +import ua.net.uid.utils.db.old.annotation.Columns; +import ua.net.uid.utils.db.old.annotation.PrimaryKey; + +public class EntityObject extends EntityField { + private final TypeElement typeElement; + private final List fields = new ArrayList<>(); + private final boolean isPrimary; + private final EntityField primaryField; + + public EntityObject(VariableElement variableElement, Map columns, EntityField parentField) { + super(variableElement, parentField); + typeElement = (TypeElement) ((DeclaredType) variableElement.asType()).asElement(); + isPrimary = variableElement.getAnnotation(PrimaryKey.class) != null; + EntityField primary = null; + for (Element element : typeElement.getEnclosedElements()) { + if (element.getKind() == ElementKind.FIELD/* || element.getKind() == ElementKind.ENUM_CONSTANT*/) { + final VariableElement variable = (VariableElement) element; + EntityField field = null; + if (variable.getAnnotation(Column.class) != null) { + field = new EntityColumn(variable, null); + columns.put(field.getName(), (EntityColumn) field); + } else if (variable.getAnnotation(PrimaryKey.class) != null || variable.getAnnotation(Columns.class) != null) { + field = new EntityObject(variable, columns, null); + } + if (field != null) { + fields.add(field); + if (field.hasPrimary()) primary = field.getPrimaryKey(); + //if (_auto == null && field.isAuto()) _auto = field.getAuto(); + } + } + } + + primaryField = isPrimary ? this : primary; + } + + @Override + public boolean hasPrimary() { return primaryField != null; } + + @Override + public boolean isPrimaryKey() { return isPrimary; } + + @Override + public EntityField getPrimaryKey() { return primaryField; } + + @Override + public void writeFetch(Appendable builder, String item) throws IOException { + final String varName = item + '_' + getVariableElement().getSimpleName(); + builder.append(" final ") + .append(typeElement.getQualifiedName()).append(' ').append(varName) + .append(" = new ").append(typeElement.getQualifiedName()).append("();\n"); + for (EntityField field : fields) { + field.writeFetch(builder, varName); + } + builder.append(" ").append(item).append('.'); + if (writeSetter(builder)) { + builder.append('(').append(varName).append(");\n"); + } else { + builder.append(" = ").append(varName).append(";\n"); + } + } + + @Override + public void writeColums(Appendable builder, String postfix, String div) throws IOException { + boolean comma = false; + for(EntityField field : fields) { + if (comma) builder.append(div); else comma = true; + field.writeColums(builder, postfix, div); + } + } +} diff --git a/src/main/java/ua/net/uid/utils/db/old/orm/Processor.java b/src/main/java/ua/net/uid/utils/db/old/orm/Processor.java new file mode 100644 index 0000000..02e02df --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/orm/Processor.java @@ -0,0 +1,89 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.orm; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import ua.net.uid.utils.db.old.annotation.Table; + +@SupportedSourceVersion(SourceVersion.RELEASE_14) +@SupportedAnnotationTypes({ + "ua.net.uid.utils.db.annotation.Table", + "ua.net.uid.utils.db.annotation.Column", + "ua.net.uid.utils.db.annotation.Columns", + +/* + "ua.net.uid.utils.orm.annotations.Table", + "ua.net.uid.utils.orm.annotations.Select", + "ua.net.uid.utils.orm.annotations.Update", + */ +}) +public class Processor extends AbstractProcessor { + + private final Map entityMetas = new HashMap<>(); + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnvironment) { + if (annotations.isEmpty()) { + return false; + } + + message(Diagnostic.Kind.ERROR, "!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + + roundEnvironment + .getElementsAnnotatedWith(Table.class) + .stream() + .filter(element -> element instanceof TypeElement) + .forEachOrdered(element -> getEntityMeta((TypeElement) element)); + //createDAOMeta(Select.class, roundEnv); + //createDAOMeta(Update.class, roundEnv); + /*for (DAOMeta generator : generators.values()) { + try { + generator.generate(processingEnv.getFiler()); + } catch (Exception ex) { + message(Diagnostic.Kind.ERROR, generator.getTypeElement().getQualifiedName()+" : "+ex.getMessage()); + } + }*/ + return true; + } + + public EntityMeta getEntityMeta(TypeElement element) { + EntityMeta result = entityMetas.get(element); + message(Diagnostic.Kind.NOTE, element.getQualifiedName()); + if (result == null) { + try { + result = new EntityMeta(this, (TypeElement) element); + result.generateFetcher(processingEnv.getFiler()); + entityMetas.put((TypeElement) element, result); + } catch (Exception ex) { + message(Diagnostic.Kind.ERROR, ((TypeElement) element).getQualifiedName() + " : " + ex.getMessage()); + } + } + return result; + } + + public void message(Diagnostic.Kind kind, CharSequence message) { + processingEnv.getMessager().printMessage(kind, message); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/old/query/Condition.java b/src/main/java/ua/net/uid/utils/db/old/query/Condition.java new file mode 100644 index 0000000..e183359 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/query/Condition.java @@ -0,0 +1,209 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.query; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public abstract class Condition implements QueryPart { + public static Condition raw(CharSequence condition, Object... params) { + if (condition == null) + throw new IllegalArgumentException("condition is null"); + return new Raw(condition, params); + } + + public static Condition not(CharSequence condition, Object... params) { + return new Not(raw(condition, params)); + } + + public static Condition not(Condition condition) { + if (condition == null) { + return null; + } else if (condition instanceof Not) { + return ((Not) condition).condition; + } else { + return new Not(condition); + } + } + + public static Condition and(Condition left, Condition right) { + if (left != null) { + return right == null ? left : new And(left, right); + } else { + return right; + } + } + + public static Condition and(Condition... conditions) { + if (conditions == null || conditions.length == 0) return null; + return conditions.length == 1 ? conditions[0] : new And(conditions); + } + + public static Condition or(Condition... conditions) { + if (conditions == null || conditions.length == 0) return null; + return conditions.length == 1 ? conditions[0] : new Or(conditions); + } + + public static Condition in(CharSequence left, Collection items) { + if (left == null || left.length() == 0) + throw new IllegalArgumentException("left side parameter for 'in' condition is null"); + if (items == null || items.isEmpty()) return null; + return new In(left, items.toArray(new Object[items.size()])); + } + + public static Condition in(CharSequence left, Object... items) { + if (left == null || left.length() == 0) + throw new IllegalArgumentException("left side parameter for 'in' condition is null"); + if (items == null || items.length == 0) return null; + return new In(left, items); + } + + public Object[] toParams(Object... post) { + ArrayList params = new ArrayList<>(); + bind(params); + if (post != null) Collections.addAll(params, post); + return params.toArray(); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + build(builder); + return builder.toString(); + } + + static final class Raw extends Condition { + private final CharSequence condition; + private final Object[] params; + + Raw(CharSequence condition, Object[] params) { + this.condition = condition; + this.params = params; + } + + @Override + public void build(StringBuilder builder) { + builder.append(condition); + } + + @Override + public void bind(List params) { + Collections.addAll(params, this.params); + } + } + + static final class Not extends Condition { + private final Condition condition; + + Not(Condition condition) { + this.condition = condition; + } + + @Override + public void build(StringBuilder builder) { + builder.append("NOT("); + condition.build(builder); + builder.append(')'); + } + + @Override + public void bind(List params) { + condition.bind(params); + } + } + + static abstract class Block extends Condition { + final List conditions; + + Block(Condition... conditions) { + this.conditions = new ArrayList<>(conditions.length); + for (Condition condition : conditions) + if (condition != null) { + if (condition.getClass() == getClass()) { + this.conditions.addAll(((Block) condition).conditions); + } else { + this.conditions.add(condition); + } + } + } + + @Override + public final void bind(List params) { + for (Condition condition : conditions) + condition.bind(params); + } + + final void build(StringBuilder builder, String div) { + if (conditions.size() > 1) { + builder.append("("); + conditions.get(0).build(builder); + for (int i = 1; i < conditions.size(); ++i) { + builder.append(div); + conditions.get(i).build(builder); + } + builder.append(")"); + } else { + conditions.get(0).build(builder); + } + } + } + + static final class And extends Block { + And(Condition... conditions) { + super(conditions); + } + + @Override + public void build(StringBuilder builder) { + build(builder, ") AND ("); + } + } + + static final class Or extends Block { + Or(Condition... conditions) { + super(conditions); + } + + @Override + public void build(StringBuilder builder) { + build(builder, ") OR ("); + } + } + + static final class In extends Condition { + private final CharSequence left; + private final Object[] items; + + public In(CharSequence left, Object[] items) { + this.left = left; + this.items = items; + } + + @Override + public void build(StringBuilder builder) { + builder.append(left).append(" IN (?"); + for (int i = 1; i < items.length; ++i) builder.append(",?"); + builder.append(')'); + } + + @Override + public void bind(List params) { + Collections.addAll(params, items); + } + } +} diff --git a/src/main/java/ua/net/uid/utils/db/old/query/Order.java b/src/main/java/ua/net/uid/utils/db/old/query/Order.java new file mode 100644 index 0000000..d4a6c8d --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/query/Order.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.query; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Order implements QueryPart { + private final StringBuilder expressions = new StringBuilder(); + private final ArrayList params = new ArrayList<>(1); + + private Order() { + } + + public static Order by() { + return new Order(); + } + + public Order asc(CharSequence expression, Object... args) { + return append(expression, " ASC", args); + } + + public Order desc(CharSequence expression, Object... args) { + return append(expression, " DESC", args); + } + + public Order ascNullFirst(CharSequence expression, Object... args) { + return append(expression, " ASC NULLS FIRST", args); + } + + public Order ascNullLast(CharSequence expression, Object... args) { + return append(expression, " ASC NULLS LAST", args); + } + + public Order descNullFirst(CharSequence expression, Object... args) { + return append(expression, " DESC NULLS FIRST", args); + } + + public Order descNullLast(CharSequence expression, Object... args) { + return append(expression, " DESC NULLS LAST", args); + } + + private Order append(CharSequence expression, String suffix, Object[] args) { + expressions.append(expressions.length() == 0 ? " ORDER BY " : ", ").append(expression).append(suffix); + if (args != null) Collections.addAll(params, args); + return this; + } + + @Override + public void build(StringBuilder builder) { + builder.append(expressions); + } + + @Override + public void bind(List params) { + params.addAll(this.params); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/old/query/Query.java b/src/main/java/ua/net/uid/utils/db/old/query/Query.java new file mode 100644 index 0000000..01a5449 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/query/Query.java @@ -0,0 +1,22 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.query; + +public interface Query { + String getQuery(); + + Object[] getParams(); +} diff --git a/src/main/java/ua/net/uid/utils/db/old/query/QueryBuilder.java b/src/main/java/ua/net/uid/utils/db/old/query/QueryBuilder.java new file mode 100644 index 0000000..5a6d9f4 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/query/QueryBuilder.java @@ -0,0 +1,136 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.query; + +import ua.net.uid.utils.db.Processor; +import ua.net.uid.utils.db.Session; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class QueryBuilder implements Query { + private final StringBuilder builder = new StringBuilder(); + private final List params = new ArrayList<>(); + + public QueryBuilder append(QueryPart part) { + if (part != null) { + part.build(builder); + part.bind(params); + } + return this; + } + + public QueryBuilder appendIf(boolean con, QueryPart part) { + if (con && part != null) { + part.build(builder); + part.bind(params); + } + return this; + } + + public QueryBuilder append(CharSequence prefix, QueryPart part) { + if (part != null) { + builder.append(prefix); + part.build(builder); + part.bind(params); + } + return this; + } + + public QueryBuilder appendIf(boolean con, CharSequence prefix, QueryPart part) { + if (con && part != null) { + builder.append(prefix); + part.build(builder); + part.bind(params); + } + return this; + } + + public QueryBuilder append(CharSequence part) { + if (part != null) + builder.append(part); + return this; + } + + public QueryBuilder appendIf(boolean con, CharSequence part) { + if (con && part != null) + builder.append(part); + return this; + } + + public QueryBuilder append(CharSequence part, Object... params) { + if (part == null || part.length() == 0) + throw new IllegalArgumentException("not empty part required"); + builder.append(part); + Collections.addAll(this.params, params); + return this; + } + + public QueryBuilder appendIf(boolean con, CharSequence part, Object... params) { + if (con) { + if (part == null || part.length() == 0) + throw new IllegalArgumentException("not empty part required"); + builder.append(part); + Collections.addAll(this.params, params); + } + return this; + } + + public QueryBuilder append(String part) { + if (part != null) + builder.append(part); + return this; + } + + public QueryBuilder appendIf(boolean con, String part) { + if (con && part != null) + builder.append(part); + return this; + } + + public QueryBuilder append(String part, Object... params) { + if (part == null || part.length() == 0) + throw new IllegalArgumentException("not empty part required"); + builder.append(part); + Collections.addAll(this.params, params); + return this; + } + + public QueryBuilder appendIf(boolean con, String part, Object... params) { + if (con) { + if (part == null || part.length() == 0) + throw new IllegalArgumentException("not empty part required"); + builder.append(part); + Collections.addAll(this.params, params); + } + return this; + } + + public Processor on(Session session) { + return session.query(getQuery(), getParams()); + } + + @Override + public String getQuery() { + return builder.toString(); + } + + @Override + public Object[] getParams() { + return params.toArray(); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/old/query/QueryPart.java b/src/main/java/ua/net/uid/utils/db/old/query/QueryPart.java new file mode 100644 index 0000000..4ffb6b3 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/old/query/QueryPart.java @@ -0,0 +1,24 @@ +/* + * Copyright 2020 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.old.query; + +import java.util.List; + +public interface QueryPart { + void build(StringBuilder builder); + + void bind(List params); +} diff --git a/src/main/java/ua/net/uid/utils/db/orm/FetcherBuilder.java b/src/main/java/ua/net/uid/utils/db/orm/FetcherBuilder.java new file mode 100644 index 0000000..93ba561 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/orm/FetcherBuilder.java @@ -0,0 +1,74 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.orm; + +import java.io.IOException; + +class FetcherBuilder { + private final Meta.EntityMeta entityMeta; + + FetcherBuilder(Meta.EntityMeta entityMeta) { + this.entityMeta = entityMeta; + } + + void build(Appendable builder) throws IOException { + builder.append("package ").append(entityMeta.getPackageElement().getQualifiedName()) + .append(";\npublic class ").append(entityMeta.getEntitySimpleName()) + .append(" implements ").append(Utils.FETCHER_CLASS) + .append('<').append(entityMeta.getEntitySimpleName()).append("> {\n @Override\n public ") + .append(entityMeta.getEntitySimpleName()).append(" fetch(final ").append(Utils.RESULTSET_CLASS) + .append(" result) throws ").append(Utils.SQLEXCEPTION_CLASS).append(" {\n"); + + if (entityMeta.isResultSetConstructor()) { + builder.append(" return new ").append(entityMeta.getEntitySimpleName()).append("(result);\n"); + } else { + builder.append(" ").append(entityMeta.getEntitySimpleName()).append(" item = new ") + .append(entityMeta.getEntitySimpleName()).append("();\n"); + for (Meta.Field field : entityMeta.getFields()) { + buildField(builder, field, "item"); + } + builder.append(" return item;\n"); + } + builder.append(" }\n public static ").append(entityMeta.getFetcherSimpleName()) + .append(" getInstance() { return Holder.INSTANCE; }\n private ") + .append(entityMeta.getFetcherSimpleName()) + .append("() {}\n private static class Holder {\n private static final ") + .append(entityMeta.getFetcherSimpleName()) + .append(" INSTANCE = new ").append(entityMeta.getFetcherSimpleName()).append("();\n }\n}\n"); + } + + private void buildField(Appendable builder, Meta.Field field, String item) throws IOException { + if (field instanceof Meta.ColumnField) { + + } else if (field instanceof Meta.ComplexMeta) { + /* + final String varName = item + '_' + field.getVariableElement().getSimpleName(); + builder.append(" final ") + .append(field. typeElement.getQualifiedName()).append(' ').append(varName) + .append(" = new ").append(typeElement.getQualifiedName()).append("();\n"); + for (EntityField field : fields) { + field.writeFetch(builder, varName); + } + builder.append(" ").append(item).append('.'); + if (writeSetter(builder)) { + builder.append('(').append(varName).append(");\n"); + } else { + builder.append(" = ").append(varName).append(";\n"); + } + */ + } + } +} diff --git a/src/main/java/ua/net/uid/utils/db/orm/Meta.java b/src/main/java/ua/net/uid/utils/db/orm/Meta.java new file mode 100644 index 0000000..03ba7a7 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/orm/Meta.java @@ -0,0 +1,237 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.orm; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import ua.net.uid.utils.db.annotation.Column; +import ua.net.uid.utils.db.annotation.Composite; +import ua.net.uid.utils.db.annotation.Entity; +import ua.net.uid.utils.db.annotation.PrimaryKey; + +interface Meta { + ComplexMeta getParent(); + default EntityMeta getRoot() { + return getParent().getRoot(); + } + + interface SingleMeta extends Meta { + String getColumnName(); + boolean isAutoincrement(); + boolean isNullable(); + } + + interface ComplexMeta extends Meta { + boolean isResultSetConstructor(); + List getFields(); + + default boolean scanElements(TypeElement typeElement) { + boolean resultSet = false; + for (Element element : typeElement.getEnclosedElements()) { + if (element.getKind() == ElementKind.CONSTRUCTOR) { + resultSet = Utils.isResultSetParameter((ExecutableElement)element); + } else if (element.getKind() == ElementKind.FIELD) { + scanVariableElement((VariableElement) element); + } + } + return resultSet; + } + + default void scanVariableElement(VariableElement variable) { + boolean primary = variable.getAnnotation(PrimaryKey.class) != null; + if (variable.getAnnotation(Column.class) != null) { + ColumnField field = new ColumnField(this, variable); + getFields().add(field); + getRoot().columns.put(field.columnName, field); + if (primary) { + getRoot().primaryField = field; + } + } else if (primary) { + getFields().add(getRoot().primaryField = new ObjectField(this, variable)); + } else if (variable.getAnnotation(Composite.class) != null) { + getFields().add(new ObjectField(this, variable)); + } + } + } + + abstract class Field implements Meta { + private final ComplexMeta parent; + private final VariableElement variableElement; + private final boolean isPrimary; + + public Field(ComplexMeta parent, VariableElement variable) { + this.parent = parent; + this.variableElement = variable; + this.isPrimary = variable.getAnnotation(PrimaryKey.class) != null + || (parent instanceof Field field && field.isPrimary); + } + + @Override + public ComplexMeta getParent() { + return parent; + } + + public final VariableElement getVariableElement() { + return variableElement; + } + + public final boolean isPrimary() { + return isPrimary; + } + } + + class ColumnField extends Field implements SingleMeta { + private final String columnName; + private final boolean autoincrement; + private final boolean nullable; + + public ColumnField(ComplexMeta parent, VariableElement variable) { + super(parent, variable); + Column column = variable.getAnnotation(Column.class); + this.columnName = column.name() == null || column.name().isBlank() + ? variable.getSimpleName().toString() + : column.name(); + this.autoincrement = column.autoincrement(); + this.nullable = !isPrimary() && column.nullable(); + } + + @Override + public String getColumnName() { + return columnName; + } + + @Override + public boolean isAutoincrement() { + return autoincrement; + } + + @Override + public boolean isNullable() { + return nullable; + } + } + + class ObjectField extends Field implements ComplexMeta { + private final List fields = new ArrayList<>(); + private final boolean resultSetConstructor; + + public ObjectField(ComplexMeta parent, VariableElement variable) { + super(parent, variable); + resultSetConstructor = scanElements((TypeElement) ((DeclaredType) getVariableElement().asType()).asElement()); + } + + @Override + public List getFields() { + return fields; + } + + @Override + public boolean isResultSetConstructor() { + return resultSetConstructor; + } + } + + class EntityMeta implements ComplexMeta { + private final TypeElement typeElement; + private final PackageElement packageElement; + private final String tableSchema; + private final String tableName; + private final List fields = new ArrayList<>(); + private final Map columns = new LinkedHashMap<>(); + private Field primaryField; + private final String fetcherSimpleName; + private final String fetcherQualifiedName; + private final boolean resultSetConstructor; + + public EntityMeta(TypeElement typeElement) { + this.typeElement = typeElement; + this.packageElement = Utils.getPackageElement(typeElement); + Entity entity = typeElement.getAnnotation(Entity.class); + this.tableSchema = entity.schema() == null || entity.schema().isBlank() ? null : entity.schema(); + this.tableName = entity.name() == null || entity.name().isBlank() ? typeElement.getSimpleName().toString() : entity.name(); + this.fetcherSimpleName = typeElement.getQualifiedName().toString() + .substring(packageElement.getQualifiedName().length() + 1) + .replace('.', '_') + Utils.FETCHER_SUFFIX; + this.fetcherQualifiedName = packageElement.getQualifiedName() + "." + this.fetcherSimpleName; + this.resultSetConstructor = scanElements(typeElement); + } + + @Override + public ComplexMeta getParent() { + return null; + } + + @Override + public EntityMeta getRoot() { + return this; + } + + public TypeElement getTypeElement() { + return typeElement; + } + + public PackageElement getPackageElement() { + return packageElement; + } + + public String getEntitySimpleName() { + return typeElement.getSimpleName().toString(); + } + + public String getTableSchema() { + return tableSchema; + } + + public String getTableName() { + return tableName; + } + + @Override + public List getFields() { + return fields; + } + + public Map getColumns() { + return columns; + } + + public Field getPrimaryField() { + return primaryField; + } + + @Override + public boolean isResultSetConstructor() { + return resultSetConstructor; + } + + public String getFetcherSimpleName() { + return fetcherSimpleName; + } + + public String getFetcherQualifiedName() { + return fetcherQualifiedName; + } + } +} diff --git a/src/main/java/ua/net/uid/utils/db/orm/Processor.java b/src/main/java/ua/net/uid/utils/db/orm/Processor.java new file mode 100644 index 0000000..df303f4 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/orm/Processor.java @@ -0,0 +1,79 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.orm; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import ua.net.uid.utils.db.annotation.Entity; + +@SupportedSourceVersion(SourceVersion.RELEASE_16) +@SupportedAnnotationTypes({ + "ua.net.uid.utils.db.annotation.Entity", + "ua.net.uid.utils.db.annotation.Column", + "ua.net.uid.utils.db.annotation.Composite", + "ua.net.uid.utils.db.annotation.PrimaryKey" +}) +public class Processor extends AbstractProcessor { + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnvironment) { + if (annotations.isEmpty()) { + return false; + } + Map entityMetas = new HashMap<>(); + for(Element element : roundEnvironment.getElementsAnnotatedWith(Entity.class)) { + if (element instanceof TypeElement typeElement) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, typeElement.getQualifiedName()); + try { + Meta.EntityMeta entityMeta = new Meta.EntityMeta(typeElement); + generateFetcher(entityMeta); + + entityMetas.put(typeElement, entityMeta); + + } catch (Exception ex) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, typeElement.getQualifiedName() + " : " + ex.getMessage()); + } + } + } + return true; + } + + private void generateFetcher(Meta.EntityMeta entityMeta) throws IOException { + JavaFileObject fileObject = processingEnv.getFiler().createSourceFile( + entityMeta.getFetcherQualifiedName(), + entityMeta.getPackageElement(), + entityMeta.getTypeElement() + ); + try (final Writer writer = fileObject.openWriter()) { + final BufferedWriter builder = new BufferedWriter(writer); + (new FetcherBuilder(entityMeta)).build(builder); + builder.flush(); + } + } +} diff --git a/src/main/java/ua/net/uid/utils/db/orm/Utils.java b/src/main/java/ua/net/uid/utils/db/orm/Utils.java new file mode 100644 index 0000000..8b5609d --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/orm/Utils.java @@ -0,0 +1,108 @@ +/* + * Copyright 2021 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.orm; + +import java.sql.ResultSet; +import java.sql.SQLException; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeKind; +import javax.lang.model.util.ElementFilter; +import ua.net.uid.utils.db.Fetcher; + +public class Utils { + public static final String FETCHER_SUFFIX = "$$Fetcher"; + public static final String FETCHER_CLASS = Fetcher.class.getCanonicalName(); + public static final String RESULTSET_CLASS = ResultSet.class.getCanonicalName(); + public static final String SQLEXCEPTION_CLASS = SQLException.class.getCanonicalName(); + + public static PackageElement getPackageElement(Element element) { + while(element != null && !(element instanceof PackageElement)) { + element = element.getEnclosingElement(); + } + return (PackageElement)element; + } + + public static boolean isResultSetParameter(ExecutableElement element) { + return element.getParameters().size() == 1 + && RESULTSET_CLASS.equals(element.getParameters().get(0).asType().toString()); + } + + public static boolean isAssignableFrom(TypeElement element, Class type) { + if (type.getName().equals(element.getQualifiedName().toString())) { + return true; + } + for (Class intf : type.getInterfaces()) { + if (isAssignableFrom(element, intf)) { + return true; + } + } + return (type.getSuperclass() != null && isAssignableFrom(element, type.getSuperclass())); + } + + public static ExecutableElement findSetter(String fieldName, TypeElement classElement) { + final String setter = buildName("set", fieldName); + Iterable methods = ElementFilter.methodsIn(classElement.getEnclosedElements()); + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if (setter.equalsIgnoreCase(methodName) && method.getParameters().size() == 1 && method.getReturnType().getKind().equals(TypeKind.VOID)) { + return method; + } + } + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if (fieldName.equals(methodName) && method.getParameters().size() == 1 && method.getReturnType().getKind().equals(TypeKind.VOID)) { + return method; + } + } + return null; + } + + public static ExecutableElement findGetter(String fieldName, TypeElement classElement) { + final String getter1 = buildName("get", fieldName); + final String getter2 = buildName("is", fieldName); + Iterable methods = ElementFilter.methodsIn(classElement.getEnclosedElements()); + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if ((getter1.equalsIgnoreCase(methodName) || getter2.equalsIgnoreCase(methodName)) && method.getParameters().isEmpty()) { + return method; + } + } + for (ExecutableElement method : methods) { + String methodName = method.getSimpleName().toString(); + if (fieldName.equals(methodName) && method.getParameters().isEmpty()) { + return method; + } + } + return null; + } + + private static String buildName(String prefix, String suffix) { + final StringBuilder builder = new StringBuilder(prefix.length() + suffix.length()); + builder.append(prefix); + if (suffix.length() > 0) { + builder.append(Character.toUpperCase(suffix.charAt(0))); + if (suffix.length() > 1) { + builder.append(suffix, 1, suffix.length()); + } + } + return builder.toString(); + } + + private Utils() {} +} diff --git a/src/main/java/ua/net/uid/utils/db/query/AbstractBlockExpression.java b/src/main/java/ua/net/uid/utils/db/query/AbstractBlockExpression.java new file mode 100644 index 0000000..4661c2b --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/AbstractBlockExpression.java @@ -0,0 +1,74 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +abstract class AbstractBlockExpression implements Expression { + private final List expressions; + + public AbstractBlockExpression(Expression... expressions) { + this.expressions = new ArrayList<>(expressions.length); + for (Expression expression : expressions) { + add(expression); + } + } + + public List getExpressions() { + return expressions; + } + + public AbstractBlockExpression or(Expression... expressions) { + add(new OrExpression(expressions)); + return this; + } + + public AbstractBlockExpression and(Expression... expressions) { + add(new AndExpression(expressions)); + return this; + } + + public AbstractBlockExpression xor(Expression... expressions) { + add(new XorExpression(expressions)); + return this; + } + + protected void add(Expression expression) { + if (expression != null) { + this.expressions.add(expression); + } + } + + @Override + public Expression validate() { + ListIterator it = expressions.listIterator(); + while (it.hasNext()) { + Expression expression = it.next(), other; + if (expression == null || (other = expression.validate()) == null) { + it.remove(); + } else if (other != expression) { + it.set(other); + } + } + return switch (expressions.size()) { + case 0 -> null; + case 1 -> expressions.get(0); + default -> this; + }; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/AndExpression.java b/src/main/java/ua/net/uid/utils/db/query/AndExpression.java new file mode 100644 index 0000000..8505d59 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/AndExpression.java @@ -0,0 +1,41 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class AndExpression extends AbstractBlockExpression { + public AndExpression(Expression... expressions) { + super(expressions); + } + + @Override + public AndExpression and(Expression... expressions) { + for (Expression expression : expressions) { + add(expression); + } + return this; + } + + @Override + protected void add(Expression expression) { + if (expression instanceof AndExpression andExpression) { + for (Expression item : andExpression.getExpressions()) { + super.add(item); + } + } else { + super.add(expression); + } + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/BetweenExpression.java b/src/main/java/ua/net/uid/utils/db/query/BetweenExpression.java new file mode 100644 index 0000000..47bc2cc --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/BetweenExpression.java @@ -0,0 +1,50 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class BetweenExpression implements Expression { + private final Expression expression; + private final boolean symmetric; + private final Exception left; + private final Exception right; + + public BetweenExpression(Expression expression, boolean symmetric, Exception left, Exception right) { + this.expression = expression; + this.symmetric = symmetric; + this.left = left; + this.right = right; + } + + public BetweenExpression(Expression expression, Exception left, Exception right) { + this(expression, false, left, right); + } + + public Expression getExpression() { + return expression; + } + + public boolean isSymmetric() { + return symmetric; + } + + public Exception getLeft() { + return left; + } + + public Exception getRight() { + return right; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/CallExpression.java b/src/main/java/ua/net/uid/utils/db/query/CallExpression.java new file mode 100644 index 0000000..387af4f --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/CallExpression.java @@ -0,0 +1,35 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + + +public class CallExpression implements Expression { + final CharSequence name; + final Expression[] arguments; + + public CallExpression(CharSequence name, Expression... arguments) { + this.name = name; + this.arguments = arguments; + } + + public CharSequence getName() { + return name; + } + + public Expression[] getArguments() { + return arguments; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/CaseExpression.java b/src/main/java/ua/net/uid/utils/db/query/CaseExpression.java new file mode 100644 index 0000000..7e5c188 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/CaseExpression.java @@ -0,0 +1,65 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author nightfall + */ +public class CaseExpression implements Expression { + public static class WhenExpression implements Serializable { + private final Expression when; + private final Expression then; + + public WhenExpression(Expression when, Expression then) { + this.when = when; + this.then = then; + } + + public Expression getWhen() { + return when; + } + + public Expression getThen() { + return then; + } + } + + private final List whens = new ArrayList<>(); + private Expression otherwise; + + public CaseExpression when(Expression when, Expression then) { + whens.add(new WhenExpression(when, then)); + return this; + } + + public CaseExpression otherwise(Expression otherwise) { + this.otherwise = otherwise; + return this; + } + + public List getWhens() { + return whens; + } + + public Expression getOtherwise() { + return otherwise; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/CaseValueExpression.java b/src/main/java/ua/net/uid/utils/db/query/CaseValueExpression.java new file mode 100644 index 0000000..ac5acfd --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/CaseValueExpression.java @@ -0,0 +1,32 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +/** + * + * @author nightfall + */ +public class CaseValueExpression extends CaseExpression { + private final Expression expression; + + public CaseValueExpression(Expression expression) { + this.expression = expression; + } + + public Expression getExpression() { + return expression; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/ComparisonExpression.java b/src/main/java/ua/net/uid/utils/db/query/ComparisonExpression.java new file mode 100644 index 0000000..f253eb9 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/ComparisonExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public abstract class ComparisonExpression implements InvertibleExpression { + final Exception left; + final Exception right; + + public ComparisonExpression(Exception left, Exception right) { + this.left = left; + this.right = right; + } + + public Exception getLeft() { + return left; + } + + public Exception getRight() { + return right; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/Condition.java b/src/main/java/ua/net/uid/utils/db/query/Condition.java deleted file mode 100644 index 8fec961..0000000 --- a/src/main/java/ua/net/uid/utils/db/query/Condition.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2020 nightfall. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ua.net.uid.utils.db.query; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public abstract class Condition implements QueryPart { - public static Condition raw(CharSequence condition, Object... params) { - if (condition == null) - throw new IllegalArgumentException("condition is null"); - return new Raw(condition, params); - } - - public static Condition not(CharSequence condition, Object... params) { - return new Not(raw(condition, params)); - } - - public static Condition not(Condition condition) { - if (condition == null) { - return null; - } else if (condition instanceof Not) { - return ((Not) condition).condition; - } else { - return new Not(condition); - } - } - - public static Condition and(Condition left, Condition right) { - if (left != null) { - return right == null ? left : new And(left, right); - } else { - return right; - } - } - - public static Condition and(Condition... conditions) { - if (conditions == null || conditions.length == 0) return null; - return conditions.length == 1 ? conditions[0] : new And(conditions); - } - - public static Condition or(Condition... conditions) { - if (conditions == null || conditions.length == 0) return null; - return conditions.length == 1 ? conditions[0] : new Or(conditions); - } - - public static Condition in(CharSequence left, Collection items) { - if (left == null || left.length() == 0) - throw new IllegalArgumentException("left side parameter for 'in' condition is null"); - if (items == null || items.isEmpty()) return null; - return new In(left, items.toArray(new Object[items.size()])); - } - - public static Condition in(CharSequence left, Object... items) { - if (left == null || left.length() == 0) - throw new IllegalArgumentException("left side parameter for 'in' condition is null"); - if (items == null || items.length == 0) return null; - return new In(left, items); - } - - public Object[] toParams(Object... post) { - ArrayList params = new ArrayList<>(); - bind(params); - if (post != null) Collections.addAll(params, post); - return params.toArray(); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - build(builder); - return builder.toString(); - } - - static final class Raw extends Condition { - private final CharSequence condition; - private final Object[] params; - - Raw(CharSequence condition, Object[] params) { - this.condition = condition; - this.params = params; - } - - @Override - public void build(StringBuilder builder) { - builder.append(condition); - } - - @Override - public void bind(List params) { - Collections.addAll(params, this.params); - } - } - - static final class Not extends Condition { - private final Condition condition; - - Not(Condition condition) { - this.condition = condition; - } - - @Override - public void build(StringBuilder builder) { - builder.append("NOT("); - condition.build(builder); - builder.append(')'); - } - - @Override - public void bind(List params) { - condition.bind(params); - } - } - - static abstract class Block extends Condition { - final List conditions; - - Block(Condition... conditions) { - this.conditions = new ArrayList<>(conditions.length); - for (Condition condition : conditions) - if (condition != null) { - if (condition.getClass() == getClass()) { - this.conditions.addAll(((Block) condition).conditions); - } else { - this.conditions.add(condition); - } - } - } - - @Override - public final void bind(List params) { - for (Condition condition : conditions) - condition.bind(params); - } - - final void build(StringBuilder builder, String div) { - if (conditions.size() > 1) { - builder.append("("); - conditions.get(0).build(builder); - for (int i = 1; i < conditions.size(); ++i) { - builder.append(div); - conditions.get(i).build(builder); - } - builder.append(")"); - } else { - conditions.get(0).build(builder); - } - } - } - - static final class And extends Block { - And(Condition... conditions) { - super(conditions); - } - - @Override - public void build(StringBuilder builder) { - build(builder, ") AND ("); - } - } - - static final class Or extends Block { - Or(Condition... conditions) { - super(conditions); - } - - @Override - public void build(StringBuilder builder) { - build(builder, ") OR ("); - } - } - - static final class In extends Condition { - private final CharSequence left; - private final Object[] items; - - public In(CharSequence left, Object[] items) { - this.left = left; - this.items = items; - } - - @Override - public void build(StringBuilder builder) { - builder.append(left).append(" IN (?"); - for (int i = 1; i < items.length; ++i) builder.append(",?"); - builder.append(')'); - } - - @Override - public void bind(List params) { - Collections.addAll(params, items); - } - } -} diff --git a/src/main/java/ua/net/uid/utils/db/query/EqualsExpression.java b/src/main/java/ua/net/uid/utils/db/query/EqualsExpression.java new file mode 100644 index 0000000..06c987f --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/EqualsExpression.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class EqualsExpression extends ComparisonExpression { + public EqualsExpression(Exception left, Exception right) { + super(left, right); + } + + @Override + public NotEqualsExpression getInverted() { + return new NotEqualsExpression(getLeft(), getRight()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/Expression.java b/src/main/java/ua/net/uid/utils/db/query/Expression.java new file mode 100644 index 0000000..47833f1 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/Expression.java @@ -0,0 +1,24 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +import java.io.Serializable; + +public interface Expression extends Serializable { + default Expression validate() { + return this; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/GreatEqExpression.java b/src/main/java/ua/net/uid/utils/db/query/GreatEqExpression.java new file mode 100644 index 0000000..bbc168e --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/GreatEqExpression.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class GreatEqExpression extends ComparisonExpression { + public GreatEqExpression(Exception left, Exception right) { + super(left, right); + } + + @Override + public Expression getInverted() { + return new LessExpression(getLeft(), getRight()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/GreatExpression.java b/src/main/java/ua/net/uid/utils/db/query/GreatExpression.java new file mode 100644 index 0000000..7f4b0a0 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/GreatExpression.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class GreatExpression extends ComparisonExpression { + public GreatExpression(Exception left, Exception right) { + super(left, right); + } + + @Override + public Expression getInverted() { + return new LessEqExpression(getLeft(), getRight()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/InExpression.java b/src/main/java/ua/net/uid/utils/db/query/InExpression.java new file mode 100644 index 0000000..ae24b49 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/InExpression.java @@ -0,0 +1,28 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public abstract class InExpression implements InvertibleExpression { + private final Expression expression; + + public InExpression(Expression expression) { + this.expression = expression; + } + + public Expression getExpression() { + return expression; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/InListExpression.java b/src/main/java/ua/net/uid/utils/db/query/InListExpression.java new file mode 100644 index 0000000..28313e4 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/InListExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class InListExpression extends InExpression { + private final Expression[] values; + + public InListExpression(Expression expression, Expression... values) { + super(expression); + this.values = values; + } + + public Expression[] getValues() { + return values; + } + + @Override + public Expression getInverted() { + return new NotInListExpression(getExpression(), getValues()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/InQueryExpression.java b/src/main/java/ua/net/uid/utils/db/query/InQueryExpression.java new file mode 100644 index 0000000..c468128 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/InQueryExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class InQueryExpression extends InExpression { + private final ResultQuery query; + + public InQueryExpression(Expression expression, ResultQuery query) { + super(expression); + this.query = query; + } + + public ResultQuery getQuery() { + return query; + } + + @Override + public Expression getInverted() { + return new NotInQueryExpression(getExpression(), getQuery()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/InvertibleExpression.java b/src/main/java/ua/net/uid/utils/db/query/InvertibleExpression.java new file mode 100644 index 0000000..e31cd48 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/InvertibleExpression.java @@ -0,0 +1,20 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public interface InvertibleExpression extends Expression { + Expression getInverted(); +} diff --git a/src/main/java/ua/net/uid/utils/db/query/IsNotNullExpression.java b/src/main/java/ua/net/uid/utils/db/query/IsNotNullExpression.java new file mode 100644 index 0000000..a798cc1 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/IsNotNullExpression.java @@ -0,0 +1,33 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class IsNotNullExpression implements InvertibleExpression { + final Expression expression; + + public IsNotNullExpression(Expression expression) { + this.expression = expression; + } + + public Expression getExpression() { + return expression; + } + + @Override + public IsNullExpression getInverted() { + return new IsNullExpression(expression); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/IsNullExpression.java b/src/main/java/ua/net/uid/utils/db/query/IsNullExpression.java new file mode 100644 index 0000000..f9b3b98 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/IsNullExpression.java @@ -0,0 +1,33 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class IsNullExpression implements InvertibleExpression { + final Expression expression; + + public IsNullExpression(Expression expression) { + this.expression = expression; + } + + public Expression getExpression() { + return expression; + } + + @Override + public IsNotNullExpression getInverted() { + return new IsNotNullExpression(expression); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/LessEqExpression.java b/src/main/java/ua/net/uid/utils/db/query/LessEqExpression.java new file mode 100644 index 0000000..a466991 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/LessEqExpression.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class LessEqExpression extends ComparisonExpression { + public LessEqExpression(Exception left, Exception right) { + super(left, right); + } + + @Override + public GreatExpression getInverted() { + return new GreatExpression(getLeft(), getRight()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/LessExpression.java b/src/main/java/ua/net/uid/utils/db/query/LessExpression.java new file mode 100644 index 0000000..851da2a --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/LessExpression.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class LessExpression extends ComparisonExpression { + public LessExpression(Exception left, Exception right) { + super(left, right); + } + + @Override + public Expression getInverted() { + return new GreatEqExpression(getLeft(), getRight()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/NameExpression.java b/src/main/java/ua/net/uid/utils/db/query/NameExpression.java new file mode 100644 index 0000000..94051df --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/NameExpression.java @@ -0,0 +1,20 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public interface NameExpression extends Expression { + public CharSequence[] getName(); +} diff --git a/src/main/java/ua/net/uid/utils/db/query/NotEqualsExpression.java b/src/main/java/ua/net/uid/utils/db/query/NotEqualsExpression.java new file mode 100644 index 0000000..4ffbe97 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/NotEqualsExpression.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class NotEqualsExpression extends ComparisonExpression { + public NotEqualsExpression(Exception left, Exception right) { + super(left, right); + } + + @Override + public EqualsExpression getInverted() { + return new EqualsExpression(getLeft(), getRight()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/NotExpression.java b/src/main/java/ua/net/uid/utils/db/query/NotExpression.java new file mode 100644 index 0000000..2c9ac72 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/NotExpression.java @@ -0,0 +1,33 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class NotExpression implements InvertibleExpression { + final Expression expression; + + public NotExpression(Expression expression) { + this.expression = expression; + } + + public Expression getExpression() { + return expression; + } + + @Override + public Expression getInverted() { + return expression; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/NotInListExpression.java b/src/main/java/ua/net/uid/utils/db/query/NotInListExpression.java new file mode 100644 index 0000000..d96c53b --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/NotInListExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class NotInListExpression extends InExpression { + private final Expression[] values; + + public NotInListExpression(Expression expression, Expression... values) { + super(expression); + this.values = values; + } + + public Expression[] getValues() { + return values; + } + + @Override + public Expression getInverted() { + return new InListExpression(getExpression(), getValues()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/NotInQueryExpression.java b/src/main/java/ua/net/uid/utils/db/query/NotInQueryExpression.java new file mode 100644 index 0000000..5c13606 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/NotInQueryExpression.java @@ -0,0 +1,35 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + + +public class NotInQueryExpression extends InExpression { + final ResultQuery query; + + public NotInQueryExpression(Expression expression, ResultQuery query) { + super(expression); + this.query = query; + } + + public ResultQuery getQuery() { + return query; + } + + @Override + public Expression getInverted() { + return new InQueryExpression(getExpression(), getQuery()); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/OrExpression.java b/src/main/java/ua/net/uid/utils/db/query/OrExpression.java new file mode 100644 index 0000000..4355ec7 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/OrExpression.java @@ -0,0 +1,41 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class OrExpression extends AbstractBlockExpression { + public OrExpression(Expression... expressions) { + super(expressions); + } + + @Override + public OrExpression or(Expression... expressions) { + for (Expression expression : expressions) { + add(expression); + } + return this; + } + + @Override + protected void add(Expression expression) { + if (expression instanceof OrExpression orExpression) { + for (Expression item : orExpression.getExpressions()) { + super.add(item); + } + } else { + super.add(expression); + } + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/Order.java b/src/main/java/ua/net/uid/utils/db/query/Order.java index 19bd5c6..6dae6b0 100644 --- a/src/main/java/ua/net/uid/utils/db/query/Order.java +++ b/src/main/java/ua/net/uid/utils/db/query/Order.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 nightfall. + * Copyright 2022 nightfall. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,57 +16,109 @@ package ua.net.uid.utils.db.query; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class Order implements QueryPart { - private final StringBuilder expressions = new StringBuilder(); - private final ArrayList params = new ArrayList<>(1); - - private Order() { + public static enum Direction { + ASC, DESC } + + public static enum NullsDirection { + NULLS_FIRST, NULLS_LAST + } + + public static class SortSpecification { + private final Expression expression; + private final Direction direction; + private final NullsDirection nulls; + public SortSpecification(Expression expression, Direction direction, NullsDirection nulls) { + this.expression = expression; + this.direction = direction; + this.nulls = nulls; + } + + public Expression getExpression() { + return expression; + } + + public Direction getDirection() { + return direction; + } + + public NullsDirection getNulls() { + return nulls; + } + } + + private final List sorts = new ArrayList<>(); + public static Order by() { return new Order(); } - public Order asc(CharSequence expression, Object... args) { - return append(expression, " ASC", args); - } - - public Order desc(CharSequence expression, Object... args) { - return append(expression, " DESC", args); - } - - public Order ascNullFirst(CharSequence expression, Object... args) { - return append(expression, " ASC NULLS FIRST", args); - } - - public Order ascNullLast(CharSequence expression, Object... args) { - return append(expression, " ASC NULLS LAST", args); - } - - public Order descNullFirst(CharSequence expression, Object... args) { - return append(expression, " DESC NULLS FIRST", args); - } - - public Order descNullLast(CharSequence expression, Object... args) { - return append(expression, " DESC NULLS LAST", args); - } - - private Order append(CharSequence expression, String suffix, Object[] args) { - expressions.append(expressions.length() == 0 ? " ORDER BY " : ", ").append(expression).append(suffix); - if (args != null) Collections.addAll(params, args); + public Order append(Expression expression, Direction direction, NullsDirection nulls) { + sorts.add(new SortSpecification(expression, direction, nulls)); return this; } - - @Override - public void build(StringBuilder builder) { - builder.append(expressions); + + public Order asc(Expression expression, NullsDirection nulls) { + return append(expression, Direction.ASC, nulls); } - @Override - public void bind(List params) { - params.addAll(this.params); + public Order asc(Expression expression) { + return asc(expression, null); + } + + public Order asc(CharSequence expression, Object ... parameters) { + return asc(Query.raw(expression, parameters), null); + } + + public Order ascNullsFirst(Expression expression) { + return asc(expression, NullsDirection.NULLS_FIRST); + } + + public Order ascNullsFirst(CharSequence expression, Object ... parameters) { + return asc(Query.raw(expression, parameters), NullsDirection.NULLS_FIRST); + } + + public Order ascNullsLast(Expression expression) { + return asc(expression, NullsDirection.NULLS_LAST); + } + + public Order ascNullsLast(CharSequence expression, Object ... parameters) { + return asc(Query.raw(expression, parameters), NullsDirection.NULLS_LAST); + } + + public Order desc(Expression expression, NullsDirection nulls) { + return append(expression, Direction.DESC, nulls); + } + + public Order desc(Expression expression) { + return desc(expression, null); + } + + public Order desc(CharSequence expression, Object ... parameters) { + return desc(Query.raw(expression, parameters), null); + } + + public Order descNullsFirst(Expression expression) { + return desc(expression, NullsDirection.NULLS_FIRST); + } + + public Order descNullsFirst(CharSequence expression, Object ... parameters) { + return desc(Query.raw(expression, parameters), NullsDirection.NULLS_FIRST); + } + + public Order descNullsLast(Expression expression) { + return desc(expression, NullsDirection.NULLS_LAST); + } + + public Order descNullsLast(CharSequence expression, Object ... parameters) { + return desc(Query.raw(expression, parameters), NullsDirection.NULLS_LAST); + } + + public List getSorts() { + return sorts; } } diff --git a/src/main/java/ua/net/uid/utils/db/query/OverlappingExpression.java b/src/main/java/ua/net/uid/utils/db/query/OverlappingExpression.java new file mode 100644 index 0000000..4416f15 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/OverlappingExpression.java @@ -0,0 +1,27 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class OverlappingExpression extends ComparisonExpression { + public OverlappingExpression(Exception left, Exception right) { + super(left, right); + } + + @Override + public Expression getInverted() { + return new NotExpression(this); + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/Query.java b/src/main/java/ua/net/uid/utils/db/query/Query.java index bc29f5f..dae106b 100644 --- a/src/main/java/ua/net/uid/utils/db/query/Query.java +++ b/src/main/java/ua/net/uid/utils/db/query/Query.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 nightfall. + * Copyright 2022 nightfall. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,81 @@ */ package ua.net.uid.utils.db.query; -public interface Query { - String getQuery(); +import java.io.Serializable; - Object[] getParams(); +public interface Query extends Serializable { + public static Raw raw(CharSequence text, Object ... parameters) { + return new Raw(text, parameters); + } + public static NameExpression name(CharSequence ... name) { + return new TitleExpression(name); + } + public static ValueExpression value(Object value) { + return new ValueExpression(value); + } + public static OrExpression or(Expression ... expressions) { + return new OrExpression(expressions); + } + public static AndExpression and(Expression ... expressions) { + return new AndExpression(expressions); + } + public static XorExpression xor(Expression ... expressions) { + return new XorExpression(expressions); + } + public static Expression not(Expression expression) { + return expression instanceof InvertibleExpression invertible + ? invertible.getInverted() + : new NotExpression(expression); + } + public static IsNullExpression isNull(Expression expression) { + return new IsNullExpression(expression); + } + public static IsNotNullExpression isNotNull(Expression expression) { + return new IsNotNullExpression(expression); + } + public static EqualsExpression eq(Exception left, Exception right) { + return new EqualsExpression(left, right); + } + public static NotEqualsExpression notEq(Exception left, Exception right) { + return new NotEqualsExpression(left, right); + } + public static LessExpression lt(Exception left, Exception right) { + return new LessExpression(left, right); + } + public static LessEqExpression ltEq(Exception left, Exception right) { + return new LessEqExpression(left, right); + } + public static GreatExpression gt(Exception left, Exception right) { + return new GreatExpression(left, right); + } + public static GreatEqExpression gtEq(Exception left, Exception right) { + return new GreatEqExpression(left, right); + } + public static OverlappingExpression ol(Exception left, Exception right) { + return new OverlappingExpression(left, right); + } + public static BetweenExpression between(Expression expression, boolean symmetric, Exception left, Exception right) { + return new BetweenExpression(expression, symmetric, left, right); + } + public static BetweenExpression between(Expression expression, Exception left, Exception right) { + return new BetweenExpression(expression, left, right); + } + public static CaseExpression caseOf() { + return new CaseExpression(); + } + public static CaseValueExpression caseOf(Expression expression) { + return new CaseValueExpression(expression); + } + public static InQueryExpression in(Expression expression, ResultQuery query) { + return new InQueryExpression(expression, query); + } + public static NotInQueryExpression notIn(Expression expression, ResultQuery query) { + return new NotInQueryExpression(expression, query); + } + public static InListExpression in(Expression expression, Expression ... expressions) { + return new InListExpression(expression, expressions); + } + public static NotInListExpression notIn(Expression expression, Expression ... expressions) { + return new NotInListExpression(expression, expressions); + } } diff --git a/src/main/java/ua/net/uid/utils/db/query/QueryBuilder.java b/src/main/java/ua/net/uid/utils/db/query/QueryBuilder.java deleted file mode 100644 index 1222a74..0000000 --- a/src/main/java/ua/net/uid/utils/db/query/QueryBuilder.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2020 nightfall. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ua.net.uid.utils.db.query; - -import ua.net.uid.utils.db.Processor; -import ua.net.uid.utils.db.Session; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class QueryBuilder implements Query { - private final StringBuilder builder = new StringBuilder(); - private final List params = new ArrayList<>(); - - public QueryBuilder append(QueryPart part) { - if (part != null) { - part.build(builder); - part.bind(params); - } - return this; - } - - public QueryBuilder appendIf(boolean con, QueryPart part) { - if (con && part != null) { - part.build(builder); - part.bind(params); - } - return this; - } - - public QueryBuilder append(CharSequence prefix, QueryPart part) { - if (part != null) { - builder.append(prefix); - part.build(builder); - part.bind(params); - } - return this; - } - - public QueryBuilder appendIf(boolean con, CharSequence prefix, QueryPart part) { - if (con && part != null) { - builder.append(prefix); - part.build(builder); - part.bind(params); - } - return this; - } - - public QueryBuilder append(CharSequence part) { - if (part != null) - builder.append(part); - return this; - } - - public QueryBuilder appendIf(boolean con, CharSequence part) { - if (con && part != null) - builder.append(part); - return this; - } - - public QueryBuilder append(CharSequence part, Object... params) { - if (part == null || part.length() == 0) - throw new IllegalArgumentException("not empty part required"); - builder.append(part); - Collections.addAll(this.params, params); - return this; - } - - public QueryBuilder appendIf(boolean con, CharSequence part, Object... params) { - if (con) { - if (part == null || part.length() == 0) - throw new IllegalArgumentException("not empty part required"); - builder.append(part); - Collections.addAll(this.params, params); - } - return this; - } - - public QueryBuilder append(String part) { - if (part != null) - builder.append(part); - return this; - } - - public QueryBuilder appendIf(boolean con, String part) { - if (con && part != null) - builder.append(part); - return this; - } - - public QueryBuilder append(String part, Object... params) { - if (part == null || part.length() == 0) - throw new IllegalArgumentException("not empty part required"); - builder.append(part); - Collections.addAll(this.params, params); - return this; - } - - public QueryBuilder appendIf(boolean con, String part, Object... params) { - if (con) { - if (part == null || part.length() == 0) - throw new IllegalArgumentException("not empty part required"); - builder.append(part); - Collections.addAll(this.params, params); - } - return this; - } - - public Processor on(Session session) { - return session.query(getQuery(), getParams()); - } - - @Override - public String getQuery() { - return builder.toString(); - } - - @Override - public Object[] getParams() { - return params.toArray(); - } -} diff --git a/src/main/java/ua/net/uid/utils/db/query/QueryPart.java b/src/main/java/ua/net/uid/utils/db/query/QueryPart.java index 53401a9..d1aa26b 100644 --- a/src/main/java/ua/net/uid/utils/db/query/QueryPart.java +++ b/src/main/java/ua/net/uid/utils/db/query/QueryPart.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 nightfall. + * Copyright 2022 nightfall. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,6 @@ */ package ua.net.uid.utils.db.query; -import java.util.List; +import java.io.Serializable; -public interface QueryPart { - void build(StringBuilder builder); - - void bind(List params); -} +public interface QueryPart extends Serializable {} diff --git a/src/main/java/ua/net/uid/utils/db/query/Raw.java b/src/main/java/ua/net/uid/utils/db/query/Raw.java new file mode 100644 index 0000000..bf9fbf4 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/Raw.java @@ -0,0 +1,34 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class Raw implements Query, QueryPart, Expression { + final CharSequence text; + final Object[] parameters; + + public Raw(CharSequence text, Object... parameters) { + this.text = text; + this.parameters = parameters; + } + + public CharSequence getText() { + return text; + } + + public Object[] getParameters() { + return parameters; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/ResultQuery.java b/src/main/java/ua/net/uid/utils/db/query/ResultQuery.java new file mode 100644 index 0000000..e0e0688 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/ResultQuery.java @@ -0,0 +1,18 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public interface ResultQuery extends Query {} diff --git a/src/main/java/ua/net/uid/utils/db/query/TitleExpression.java b/src/main/java/ua/net/uid/utils/db/query/TitleExpression.java new file mode 100644 index 0000000..aea8499 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/TitleExpression.java @@ -0,0 +1,29 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class TitleExpression implements NameExpression { + final CharSequence[] name; + + public TitleExpression(CharSequence... name) { + this.name = name; + } + + @Override + public CharSequence[] getName() { + return name; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/ValueExpression.java b/src/main/java/ua/net/uid/utils/db/query/ValueExpression.java new file mode 100644 index 0000000..db9a667 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/ValueExpression.java @@ -0,0 +1,28 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class ValueExpression implements Expression { + private final Object value; + + public ValueExpression(Object value) { + this.value = value; + } + + public Object getValue() { + return value; + } +} diff --git a/src/main/java/ua/net/uid/utils/db/query/XorExpression.java b/src/main/java/ua/net/uid/utils/db/query/XorExpression.java new file mode 100644 index 0000000..e91b9b3 --- /dev/null +++ b/src/main/java/ua/net/uid/utils/db/query/XorExpression.java @@ -0,0 +1,41 @@ +/* + * Copyright 2022 nightfall. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ua.net.uid.utils.db.query; + +public class XorExpression extends AbstractBlockExpression { + public XorExpression(Expression... expressions) { + super(expressions); + } + + @Override + public XorExpression xor(Expression... expressions) { + for (Expression expression : expressions) { + add(expression); + } + return this; + } + + @Override + protected void add(Expression expression) { + if (expression instanceof XorExpression xorExpression) { + for (Expression item : xorExpression.getExpressions()) { + super.add(item); + } + } else { + super.add(expression); + } + } +} diff --git a/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..359e411 --- /dev/null +++ b/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +ua.net.uid.utils.db.orm.Processor diff --git a/src/test/java/ua/net/uid/utils/db/dao/DAOAbstractTest.java b/src/test/java/ua/net/uid/utils/db/dao/DAOAbstractTest.java index 9e64e47..95894ee 100644 --- a/src/test/java/ua/net/uid/utils/db/dao/DAOAbstractTest.java +++ b/src/test/java/ua/net/uid/utils/db/dao/DAOAbstractTest.java @@ -1,13 +1,15 @@ package ua.net.uid.utils.db.dao; +import ua.net.uid.utils.db.old.dao.DAOAbstract; +import ua.net.uid.utils.db.old.dao.Entity; import org.h2.jdbcx.JdbcConnectionPool; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import ua.net.uid.utils.db.*; -import ua.net.uid.utils.db.query.Condition; -import ua.net.uid.utils.db.query.Order; -import ua.net.uid.utils.db.query.QueryBuilder; +import ua.net.uid.utils.db.old.query.Condition; +import ua.net.uid.utils.db.old.query.Order; +import ua.net.uid.utils.db.old.query.QueryBuilder; import java.sql.ResultSet; import java.sql.SQLException; @@ -255,7 +257,7 @@ @Override public boolean insert(Item item) throws SQLException { - Processor processor = new QueryBuilder().append("INSERT INTO ").append(getTableName()).append( + ua.net.uid.utils.db.Processor processor = new QueryBuilder().append("INSERT INTO ").append(getTableName()).append( " (title, value, disabled, modified) VALUES (?,?,?,?)" , item.getTitle(), item.getValue(), item.isDisabled(), item.getModified() ).on(getSession()); diff --git a/src/test/java/ua/net/uid/utils/db/query/ConditionTest.java b/src/test/java/ua/net/uid/utils/db/query/ConditionTest.java index d855f50..a448003 100644 --- a/src/test/java/ua/net/uid/utils/db/query/ConditionTest.java +++ b/src/test/java/ua/net/uid/utils/db/query/ConditionTest.java @@ -1,10 +1,11 @@ package ua.net.uid.utils.db.query; +import ua.net.uid.utils.db.old.query.Condition; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; -import static ua.net.uid.utils.db.query.Condition.*; +import static ua.net.uid.utils.db.old.query.Condition.*; class ConditionTest { @Test diff --git a/src/test/java/ua/net/uid/utils/db/query/QueryBuilderTest.java b/src/test/java/ua/net/uid/utils/db/query/QueryBuilderTest.java index f7b87b6..e7549bc 100644 --- a/src/test/java/ua/net/uid/utils/db/query/QueryBuilderTest.java +++ b/src/test/java/ua/net/uid/utils/db/query/QueryBuilderTest.java @@ -1,5 +1,9 @@ package ua.net.uid.utils.db.query; +import ua.net.uid.utils.db.old.query.QueryPart; +import ua.net.uid.utils.db.old.query.Condition; +import ua.net.uid.utils.db.old.query.Order; +import ua.net.uid.utils.db.old.query.QueryBuilder; import org.junit.jupiter.api.Test; import java.util.Collections;