Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ dependencies {
// json/yaml
implementation 'org.json:json:20240303'
implementation 'org.yaml:snakeyaml'
// databases
// databases // todo: remove and add via plugin-system
runtimeOnly 'org.postgresql:postgresql'
runtimeOnly 'org.xerial:sqlite-jdbc'
// testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ public String listSchemas() {
Table pgNamespace = new Schema("pg_catalog").table("pg_namespace");
Field schemaName = pgNamespace.field("nspname").as("schema_name");
return new PostgreSQLQuery()
.from(pgNamespace)
.select(schemaName)
.where(schemaName.not_like("pg_%"))
.getSql();
.from(pgNamespace)
.select(schemaName)
.where(schemaName.not_like("pg_%"))
.getSql();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public String listTablesOfSchema(String schemaName) {

@Override
public String listColumnsOfTable(String schemaName, String tableName) {
// todo: $schema.pragme_table_info($tableName)
Selectable tableInfo = new TableValuedFunction("pragma_table_info", tableName);
return new SQLiteQuery()
.from(tableInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public interface Database {

/**
* <b>note:</b> it's recommended to use the getter instead
*
* @return a dialect appropriate {@link MetaQueryGenerator} used to fetch table-information
* @see #getSchemaNames()
* @see #getTableNamesOfSchema(String)
Expand Down Expand Up @@ -47,7 +48,7 @@ public interface Database {

/**
* @param schemaName schema of the table
* @param tableName table
* @param tableName table
* @return column-information of the table
*/
List<ColumnInformation> getColumnInformationOfTable(@NonNull String schemaName, @NonNull String tableName);
Expand All @@ -62,14 +63,14 @@ public interface Database {

/**
* @param schemaName name of the schema of the table
* @param tableName name of the table
* @param tableName name of the table
* @return that the table exists
*/
boolean existsTable(@NonNull String schemaName, @NonNull String tableName);

/**
* @param schemaName name of the schema of the table
* @param tableName name of the table
* @param schemaName name of the schema of the table
* @param tableName name of the table
* @param columnNames columns to verify
* @return that all specified columns exist on the table
*/
Expand All @@ -78,8 +79,9 @@ public interface Database {
/**
* Utility-function used to validate that a table has all {@code columns} <br>
* If {@code columns} contains {@code *} then it's directly marked as valid
* @param schemaName schema-name
* @param tableName table-name
*
* @param schemaName schema-name
* @param tableName table-name
* @param columnNames columns to check again
* @throws org.springframework.web.server.ResponseStatusException if one or more columns are not existing
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ public interface MetaQueryGenerator {
/**
* returns an SQL-Query that returns the available tables of a specific schema <br>
* format: {@code {'schema_name', 'table_name'}}
*
* @param schemaName database schema
*/
String listTablesOfSchema(String schemaName);

/**
* returns an SQL-Query that returns the column-information of a specific table of a specific schema <br>
* format: {@code {'column_name', 'type'}}
*
* @param schemaName database schema
* @param tableName table of {@code schemaName}
* @param tableName table of {@code schemaName}
*/
String listColumnsOfTable(String schemaName, String tableName);
}
23 changes: 23 additions & 0 deletions src/main/java/org/dynapi/dynapi/core/datatypes/DataType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.dynapi.dynapi.core.datatypes;

import com.fasterxml.jackson.databind.JsonNode;
import org.dynapi.openapispec.core.schema.Schema;

public interface DataType {
/**
* @return schema for /openapi
*/
Schema<?, ?> getOpenApiSchema();

/**
* @param node node to parse
* @return parsed value
*/
Object parseJsonNode(JsonNode node);

/**
* @param object saved or so object
* @return json-save object
*/
Object formatObject(Object object);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.dynapi.dynapi.core.datatypes.impl;

import com.fasterxml.jackson.databind.JsonNode;
import org.dynapi.dynapi.core.datatypes.DataType;
import org.dynapi.openapispec.core.schema.Schema;
import org.dynapi.openapispec.core.schema.TArray;

public class DataTypeArray implements DataType {
private final DataType subType;

public DataTypeArray(DataType subType) {
this.subType = subType;
}

/**
* @return schema for /openapi
*/
@Override
public Schema<?, ?> getOpenApiSchema() {
return new TArray(subType.getOpenApiSchema());
}

/**
* @param node node to parse
* @return parsed value
*/
@Override
public Object[] parseJsonNode(JsonNode node) {
assert node.isArray();
Object[] array = new Object[node.size()];
for (int i = 0; i < node.size(); i++) {
JsonNode element = node.get(i);
array[i] = subType.parseJsonNode(element);
}
return array;
}

/**
* @param object saved or so object
* @return json-save object
*/
@Override
public Object formatObject(Object object) {
if (object instanceof Object[] a) {
Object[] array = new Object[a.length];
for (int i = 0; i < a.length; i++)
array[i] = subType.formatObject(a[i]);
return array;
}
throw new IllegalArgumentException("Object is not an array");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.dynapi.dynapi.core.datatypes.impl;

import com.fasterxml.jackson.databind.JsonNode;
import org.dynapi.dynapi.core.datatypes.DataType;
import org.dynapi.openapispec.core.schema.Schema;
import org.dynapi.openapispec.core.schema.TString;

import java.util.Base64;

public class DataTypeBlob implements DataType {
/**
* @return schema for /openapi
*/
@Override
public Schema<?, ?> getOpenApiSchema() {
return new TString()
.format(TString.CommonFormats.BINARY);
}

/**
* @param node node to parse
* @return parsed value
*/
@Override
public byte[] parseJsonNode(JsonNode node) {
assert node.isTextual();
String base64String = node.textValue();
return Base64.getDecoder().decode(base64String);
}

/**
* @param object saved or so object
* @return json-save object
*/
@Override
public Object formatObject(Object object) {
if (object instanceof byte[] b)
return Base64.getEncoder().encodeToString(b);
throw new IllegalArgumentException("Object is not a blob");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.dynapi.dynapi.core.datatypes.impl;

import com.fasterxml.jackson.databind.JsonNode;
import org.dynapi.dynapi.core.datatypes.DataType;
import org.dynapi.openapispec.core.schema.Schema;
import org.dynapi.openapispec.core.schema.TBoolean;

public class DataTypeBoolean implements DataType {
/**
* @return schema for /openapi
*/
@Override
public Schema<?, ?> getOpenApiSchema() {
return new TBoolean();
}

/**
* @param node node to parse
* @return parsed value
*/
@Override
public Object parseJsonNode(JsonNode node) {
assert node.isBoolean();
return node.booleanValue();
}

/**
* @param object saved or so object
* @return json-save object
*/
@Override
public Object formatObject(Object object) {
if (object instanceof Boolean b)
return b;
throw new IllegalArgumentException("Object is not a boolean");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.dynapi.dynapi.core.datatypes.impl;

import com.fasterxml.jackson.databind.JsonNode;
import org.dynapi.dynapi.core.datatypes.DataType;
import org.dynapi.openapispec.core.schema.Schema;
import org.dynapi.openapispec.core.schema.TString;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;

public class DataTypeDate implements DataType {
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE;

/**
* @return schema for /openapi
*/
@Override
public Schema<?, ?> getOpenApiSchema() {
return new TString()
.format(TString.CommonFormats.DATE);
}

/**
* @param node node to parse
* @return parsed value
*/
@Override
public LocalDate parseJsonNode(JsonNode node) {
assert node.isTextual();
return LocalDate.parse(node.textValue(), DATE_FORMATTER);
}

/**
* @param object saved or so object
* @return json-save object
*/
@Override
public String formatObject(Object object) {
if (object instanceof LocalDateTime || object instanceof LocalDate || object instanceof Instant)
return DATE_FORMATTER.format((TemporalAccessor) object);
throw new IllegalArgumentException("Object is not a date");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.dynapi.dynapi.core.datatypes.impl;

import com.fasterxml.jackson.databind.JsonNode;
import org.dynapi.dynapi.core.datatypes.DataType;
import org.dynapi.openapispec.core.schema.Schema;
import org.dynapi.openapispec.core.schema.TString;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;

public class DataTypeDateTime implements DataType {
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

/**
* @return schema for /openapi
*/
@Override
public Schema<?, ?> getOpenApiSchema() {
return new TString()
.format(TString.CommonFormats.DATETIME);
}

/**
* @param node node to parse
* @return parsed value
*/
@Override
public LocalDateTime parseJsonNode(JsonNode node) {
assert node.isTextual();
return LocalDateTime.parse(node.textValue(), DATE_FORMATTER);
}

/**
* @param object saved or so object
* @return json-save object
*/
@Override
public String formatObject(Object object) {
if (object instanceof LocalDateTime || object instanceof LocalDate || object instanceof Instant)
return DATE_FORMATTER.format((TemporalAccessor) object);
throw new IllegalArgumentException("Object is not a date");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.dynapi.dynapi.core.datatypes.impl;

import com.fasterxml.jackson.databind.JsonNode;
import org.dynapi.dynapi.core.datatypes.DataType;
import org.dynapi.openapispec.core.schema.Schema;
import org.dynapi.openapispec.core.schema.TNumber;

public class DataTypeDecimal implements DataType {
/**
* @return schema for /openapi
*/
@Override
public Schema<?, ?> getOpenApiSchema() {
return new TNumber();
}

/**
* @param node node to parse
* @return parsed value
*/
@Override
public Number parseJsonNode(JsonNode node) {
assert node.isFloatingPointNumber();
return node.isDouble() ? node.doubleValue() : node.floatValue();
}

/**
* @param object saved or so object
* @return json-save object
*/
@Override
public Object formatObject(Object object) {
if (object instanceof Double d)
return d;
if (object instanceof Float f)
return f;
throw new IllegalArgumentException("Object is not a decimal");
}
}
Loading