Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

SQL Criteria Implementation#1394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
gtnicol wants to merge10 commits intoimmutables:master
base:master
Choose a base branch
Loading
fromgtnicol:feature/sql-criteria
Open
Show file tree
Hide file tree
Changes from1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
Major changes to remove Jackson dependencies etc.
  • Loading branch information
@gtnicol
gtnicol committedNov 25, 2022
commit00c3f337327f62d40c36c0c3dd9a69c8bd9fb814
1 change: 1 addition & 0 deletions.java-version
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
17.0.4.1
9 changes: 9 additions & 0 deletionscriteria/sql/.editorconfig
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
[*]
indent_style = space
indent_size = 2
continuation_indent_size = 4
max_line_length = 120
charset = utf-8
end_of_line = lf
insert_final_newline = true

44 changes: 39 additions & 5 deletionscriteria/sql/README.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
# Criteria Adapter for SQL databases.

**Note:** _This module is highly_ ***experimental*** _and is subject to change in the future.
The underlying implementation and APIs are likely to change in the future. Use discretion when using
this module for anything more than experimentation._

This is a minimal implementation of criteria support for SQL databases, supporting the basic
CRUD operations of entitiespersistend in single tables. It is intended to be a lightweight
alternative to other ORMs but does not compete directly or support all the features of SQL databases.
There are no dependencies in this implementation beyond basic JDBC support and Jackson.
CRUD operations of entitiespersisted in single tables. It is intended to be a lightweight
alternative to other ORMs but does not compete directlywith themor support all the features of SQL databases.
There are no dependencies in this implementation beyond basic JDBC support.

## General approach

Expand All@@ -25,14 +29,44 @@ underlying tables.
### Type conversion

Object and properties are converted to underlying SQL data types using classes
in the `conversion` package. The default `RowMapper` uses `jackson` to convert
from a row to objects, with the jackson annotations having an impact on the mapping.
in the `conversion` package. At the lower level rows are mapped to objects by calling to
the associated `RowMapper` which is registered in `RowMappers`. A `RowMapper` class and a `Setup`
class are generated for each class annotated with `SQL.Table` - for example a `Note` class would
generate a `SqlNoteSetup` class and a `SqlNoteRowMapper` class - the latter of which will be registered
into `RowMappers` when the setup class us called to get a `Backend`. Currently, this assumes a standard
immutable class builder being generated, which may or may not work if `Style` is used extensively.
Type conversion happens my looking up registered converters in `TypeConverters`. All
conversion lookups support registration of custom conversions.

#### Generic Jackson conversion
A default `RowMapper` is generated however you can also use `Jackson` to convert
from a row to objects, with the Jackson annotations having an impact on the mapping (`JsonSerializeAs` etc).
As an example, the following could be used to generate a RowMapper used in a custom setup.

```java
static <T> RowMapper<T> newRowMapper(final SqlTypeMetadata metadata) {
return row -> {
final Map<String, Object> data = new HashMap<>();
final ResultSetMetaData rm = row.getMetaData();
for (int i = 1; i <= rm.getColumnCount(); ++i) {
final String name = rm.getColumnName(i).toLowerCase(Locale.ROOT);
final SqlPropertyMetadata property = metadata.columns().get(name);
if (property != null) {
data.put(property.name(), TypeConverters.convert(property.mapping().type(), property.type(),
property.mapping().fetcher().apply(row, rm.getColumnName(i))));
}
}
return (T) MAPPER.convertValue(data, metadata.type());
};
}
```

## Limitations

- Watch,GetByKey,DeleteByKey,Upsert are not implemented
- Handling of autogenerated keys and returning keys is not supported
- Joins, sub-graphs etc. are not supported.
- Projections, aggregations, groupby etc are not supported

---
**Note:** _This module is highly_ ***experimental*** _and is subject to change in the future._
64 changes: 21 additions & 43 deletionscriteria/sql/pom.xml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,12 +14,14 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>criteria</artifactId>
<groupId>org.immutables</groupId>
<artifactId>immutables</artifactId>
<version>2.9.2-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>criteria-sql</artifactId>
<name>${project.groupId}.${project.artifactId}</name>
Expand All@@ -38,55 +40,37 @@
<type>jar</type>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>${jsr305.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<!-- Jackson is needed for our bson to jackson bridge API
Color? -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-databind.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
<groupId>org.immutables</groupId>
<artifactId>generator-processor</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${jackson.version}</version>
<groupId>org.immutables</groupId>
<artifactId>metainf</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
<version>${jackson.version}</version>
<groupId>org.immutables</groupId>
<artifactId>testing</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-guava</artifactId>
<version>${jackson.version}</version>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>${jsr305.version}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
Expand All@@ -111,11 +95,5 @@
<version>${h2.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>${liquibase.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
38 changes: 19 additions & 19 deletionscriteria/sql/src/org/immutables/criteria/sql/SQL.java
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,25 +24,25 @@
* A set of annotations specific to the SQL backend
*/
public @interface SQL {
/**
* Used to define the table an entity is mapped to. If not defined the table name will be the same as
* {@code Class.getSimpleName() }
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table {
String value() default "";
}
/**
* Used to define the table an entity is mapped to. If not defined the table name will be the same as
* {@code Class.getSimpleName() }
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table {
String value() default "";
}

/**
* Used to map a property to a column and the target column type. This will drive the use of
* {@code TypeConverters.convert()} for mapping values to/from the database.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Column {
String name() default "";
/**
* Used to map a property to a column and the target column type. This will drive the use of
* {@code TypeConverters.convert()} for mapping values to/from the database.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Column {
String name() default "";

Class<?> type();
}
Class<?> type();
}
}
138 changes: 69 additions & 69 deletionscriteria/sql/src/org/immutables/criteria/sql/SQLBackend.java
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,92 +20,92 @@
import org.immutables.criteria.backend.DefaultResult;
import org.immutables.criteria.backend.StandardOperations;
import org.immutables.criteria.sql.commands.*;
import org.immutables.criteria.sql.reflection.SQLTypeMetadata;
import org.immutables.criteria.sql.reflection.SqlTypeMetadata;
import org.reactivestreams.Publisher;

/**
* Implementation of {@code Backend} which delegates to the underlying SQL specific commands.
*/
public classSQLBackend implements Backend {
private finalSQLSetup setup;
public classSqlBackend implements Backend {
private finalSqlSetup setup;

publicSQLBackend(finalSQLSetup setup) {
this.setup = setup;
}
publicSqlBackend(finalSqlSetup setup) {
this.setup = setup;
}

public staticSQLBackend of(finalSQLSetup setup) {
return newSQLBackend(setup);
}
public staticSqlBackend of(finalSqlSetup setup) {
return newSqlBackend(setup);
}

@Override
public Session open(final Class<?> type) {
return new SQLSession(type, setup);
}
@Override
public Session open(final Class<?> type) {
return new SQLSession(type, setup);
}

public static class SQLSession implements Backend.Session {
private final Class<?> type;
private finalSQLSetup setup;
public static class SQLSession implements Backend.Session {
private final Class<?> type;
private finalSqlSetup setup;

private finalSQLTypeMetadata metadata;
private finalSqlTypeMetadata metadata;

SQLSession(final Class<?> type, finalSQLSetup setup) {
this.type = type;
this.setup = setup;
SQLSession(final Class<?> type, finalSqlSetup setup) {
this.type = type;
this.setup = setup;

metadata =SQLTypeMetadata.of(type);
}
metadata =SqlTypeMetadata.of(type);
}

publicSQLSetup setup() {
return setup;
}
publicSqlSetup setup() {
return setup;
}

publicSQLTypeMetadata metadata() {
return metadata;
}
publicSqlTypeMetadata metadata() {
return metadata;
}

@Override
public Class<?> entityType() {
return type;
}
@Override
public Class<?> entityType() {
return type;
}

@Override
public Result execute(final Operation operation) {
return DefaultResult.of(Flowable.defer(() -> executeInternal(operation)));
}
@Override
public Result execute(final Operation operation) {
return DefaultResult.of(Flowable.defer(() -> executeInternal(operation)));
}

private Publisher<?> executeInternal(final Operation operation) {
if (operation instanceof StandardOperations.Select) {
final StandardOperations.Select select = (StandardOperations.Select) operation;
finalSQLCommand command = select.query().count()
? newSQLCountCommand(this, setup, select)
: newSQLSelectCommand(this, setup, select);
return command.execute();
} else if (operation instanceof StandardOperations.Update) {
final StandardOperations.Update update = (StandardOperations.Update) operation;
finalSQLCommand command = newSQLSaveCommand(this, setup, update);
return command.execute();
} else if (operation instanceof StandardOperations.UpdateByQuery) {
final StandardOperations.UpdateByQuery update = (StandardOperations.UpdateByQuery) operation;
finalSQLCommand command = newSQLUpdateCommand(this, setup, update);
return command.execute();
} else if (operation instanceof StandardOperations.Insert) {
final StandardOperations.Insert insert = (StandardOperations.Insert) operation;
finalSQLCommand command = newSQLInsertCommand(this, setup, insert);
return command.execute();
} else if (operation instanceof StandardOperations.Delete) {
final StandardOperations.Delete delete = (StandardOperations.Delete) operation;
finalSQLCommand command = newSQLDeleteCommand(this, setup, delete);
return command.execute();
} else if (operation instanceof StandardOperations.Watch) {
throw new UnsupportedOperationException("Watch");
} else if (operation instanceof StandardOperations.DeleteByKey) {
throw new UnsupportedOperationException("DeleteByKey");
} else if (operation instanceof StandardOperations.GetByKey) {
throw new UnsupportedOperationException("GetByKey");
}
private Publisher<?> executeInternal(final Operation operation) {
if (operation instanceof StandardOperations.Select) {
final StandardOperations.Select select = (StandardOperations.Select) operation;
finalSqlCommand command = select.query().count()
? newSqlCountCommand(this, setup, select)
: newSqlSelectCommand(this, setup, select);
return command.execute();
} else if (operation instanceof StandardOperations.Update) {
final StandardOperations.Update update = (StandardOperations.Update) operation;
finalSqlCommand command = newSqlSaveCommand(this, setup, update);
return command.execute();
} else if (operation instanceof StandardOperations.UpdateByQuery) {
final StandardOperations.UpdateByQuery update = (StandardOperations.UpdateByQuery) operation;
finalSqlCommand command = newSqlUpdateCommand(this, setup, update);
return command.execute();
} else if (operation instanceof StandardOperations.Insert) {
final StandardOperations.Insert insert = (StandardOperations.Insert) operation;
finalSqlCommand command = newSqlInsertCommand(this, setup, insert);
return command.execute();
} else if (operation instanceof StandardOperations.Delete) {
final StandardOperations.Delete delete = (StandardOperations.Delete) operation;
finalSqlCommand command = newSqlDeleteCommand(this, setup, delete);
return command.execute();
} else if (operation instanceof StandardOperations.Watch) {
throw new UnsupportedOperationException("Watch");
} else if (operation instanceof StandardOperations.DeleteByKey) {
throw new UnsupportedOperationException("DeleteByKey");
} else if (operation instanceof StandardOperations.GetByKey) {
throw new UnsupportedOperationException("GetByKey");
}

return Flowable.error(new UnsupportedOperationException(String.format("Operation %s not supported by %s",
operation, SQLBackend.class.getSimpleName())));
}
return Flowable.error(new UnsupportedOperationException(String.format("Operation %s not supported by %s",
operation, SqlBackend.class.getSimpleName())));
}
}
}
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,8 +15,8 @@
*/
package org.immutables.criteria.sql;

public classSQLException extends RuntimeException {
publicSQLException(String message) {
super(message);
}
public classSqlException extends RuntimeException {
publicSqlException(String message) {
super(message);
}
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp