-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DynamoDB external datastore support library (#543)
* DynamoDB external datastore support library (Issue 69246) * Add support for querying tables * Add support for CRUD operations * Fix error with blank password and local url. Fix lint errors * Allow datetime fields to only contain the date part * Add missing implementation for getDate/1 * Add special case for queries that filter with an empty string key * Add support for binary streams * Fix NullPointerException when trying to get a binary stream from a record which does not have one * Add support for blobs, when duplicate/when none semantics. Fix datetimes * add 'as' method to cast a query to its derived type * Improve Query/Scan inference. Fix lint errors * Fix datetime fields. Fix update queries * Fix possible input types for Date and DateTime in toAttributeValue * Change DateTime->String conversion. It was shifting offsets twice to reach UTC * Simplify empty datetime parameters so there is no need manage java.util.Date and java.sql.Timestamp separaterly * Update build workflow - #596 Co-authored-by: José Echagüe <[email protected]> Co-authored-by: Gonzalo <[email protected]>
- Loading branch information
1 parent
9330d53
commit d42bbca
Showing
19 changed files
with
1,452 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<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"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>com.genexus</groupId> | ||
<artifactId>parent</artifactId> | ||
<version>${revision}${changelist}</version> | ||
</parent> | ||
|
||
<artifactId>gxdynamodb</artifactId> | ||
<name>GeneXus DynamoDB</name> | ||
|
||
<dependencyManagement> | ||
<dependencies> | ||
<dependency> | ||
<groupId>software.amazon.awssdk</groupId> | ||
<artifactId>bom</artifactId> | ||
<version>2.17.151</version> | ||
<type>pom</type> | ||
<scope>import</scope> | ||
</dependency> | ||
</dependencies> | ||
</dependencyManagement> | ||
<dependencies> | ||
<dependency> | ||
<groupId>software.amazon.awssdk</groupId> | ||
<artifactId>dynamodb</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>gxclassR</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.genexus</groupId> | ||
<artifactId>gxcommon</artifactId> | ||
<version>${project.version}</version> | ||
<scope>compile</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<finalName>gxdynamodb</finalName> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<source>8</source> | ||
<target>8</target> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
75 changes: 75 additions & 0 deletions
75
gxdynamodb/src/main/java/com/genexus/db/dynamodb/DataStoreHelperDynamoDB.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package com.genexus.db.dynamodb; | ||
|
||
import com.genexus.CommonUtil; | ||
import com.genexus.db.ServiceCursorBase; | ||
import com.genexus.db.driver.GXConnection; | ||
import com.genexus.db.driver.GXPreparedStatement; | ||
import com.genexus.db.service.GXType; | ||
import com.genexus.db.service.IQuery; | ||
import com.genexus.db.service.ServiceDataStoreHelper; | ||
|
||
import java.sql.Date; | ||
import java.sql.Timestamp; | ||
|
||
public class DataStoreHelperDynamoDB extends ServiceDataStoreHelper | ||
{ | ||
public DynamoQuery newQuery() | ||
{ | ||
return new DynamoQuery(this); | ||
} | ||
public DynamoQuery newScan() | ||
{ | ||
return new DynamoScan(this); | ||
} | ||
|
||
public DynamoDBMap Map(String name) | ||
{ | ||
return new DynamoDBMap(name); | ||
} | ||
|
||
public Object empty(GXType gxtype) | ||
{ | ||
switch(gxtype) | ||
{ | ||
case Number: | ||
case Int16: | ||
case Int32: | ||
case Int64: return 0; | ||
case Date: return new Date(CommonUtil.nullDate().getTime()); | ||
case DateTime: | ||
case DateTime2: return new Timestamp(CommonUtil.nullDate().getTime()); | ||
case Byte: | ||
case NChar: | ||
case NClob: | ||
case NVarChar: | ||
case Char: | ||
case LongVarChar: | ||
case Clob: | ||
case VarChar: | ||
case Raw: | ||
case Blob: | ||
case NText: | ||
case Text: | ||
case Image: | ||
case UniqueIdentifier: | ||
case Xml: | ||
case DateAsChar: return ""; | ||
case Boolean: return false; | ||
case Decimal: return 0f; | ||
|
||
case Geography: | ||
case Geopoint: | ||
case Geoline: | ||
case Geopolygon: | ||
|
||
case Undefined: | ||
default: return null; | ||
} | ||
} | ||
|
||
@Override | ||
public GXPreparedStatement getPreparedStatement(GXConnection con, IQuery query, ServiceCursorBase cursor, int cursorNum, boolean currentOf, Object[] parms) | ||
{ | ||
return new GXPreparedStatement(new DynamoDBPreparedStatement(con.getJDBCConnection(), (DynamoQuery)query, cursor, parms, con), con, con.getHandle(), "", cursor.getCursorId(), currentOf); | ||
} | ||
} |
147 changes: 147 additions & 0 deletions
147
gxdynamodb/src/main/java/com/genexus/db/dynamodb/DynamoDBConnection.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
package com.genexus.db.dynamodb; | ||
|
||
import com.genexus.db.service.ServiceConnection; | ||
import org.apache.commons.lang.StringUtils; | ||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; | ||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; | ||
import software.amazon.awssdk.regions.Region; | ||
import software.amazon.awssdk.services.dynamodb.DynamoDbClient; | ||
import software.amazon.awssdk.services.dynamodb.DynamoDbClientBuilder; | ||
|
||
import java.net.URI; | ||
import java.sql.ResultSet; | ||
import java.util.Enumeration; | ||
import java.util.Properties; | ||
import java.util.concurrent.Executor; | ||
|
||
public class DynamoDBConnection extends ServiceConnection | ||
{ | ||
private static final String GXDYNAMODB_VERSION = "1.0"; | ||
private static final String GXDYNAMODB_PRODUCT_NAME = "DynamoDB"; | ||
|
||
private static final String CLIENT_ID = "user"; | ||
private static final String CLIENT_SECRET = "password"; | ||
private static final String REGION = "region"; | ||
private static final String LOCAL_URL = "localurl"; | ||
|
||
|
||
DynamoDbClient mDynamoDB; | ||
Region mRegion = Region.US_EAST_1; | ||
|
||
public DynamoDBConnection(String connUrl, Properties initialConnProps) | ||
{ | ||
super(connUrl, initialConnProps); // After initialization use props variable from super class to manage properties | ||
initializeDBConnection(connUrl); | ||
} | ||
|
||
private void initializeDBConnection(String connUrl) | ||
{ | ||
String mLocalUrl = null, mClientId = null, mClientSecret = null; | ||
for(Enumeration<Object> keys = props.keys(); keys.hasMoreElements(); ) | ||
{ | ||
String key = (String)keys.nextElement(); | ||
String value = props.getProperty(key, key); | ||
switch(key.toLowerCase()) | ||
{ | ||
case LOCAL_URL: mLocalUrl = value; break; | ||
case CLIENT_ID: mClientId = value; break; | ||
case CLIENT_SECRET: mClientSecret = value; break; | ||
case REGION: mRegion = Region.of(value); break; | ||
default: break; | ||
} | ||
} | ||
DynamoDbClientBuilder builder = DynamoDbClient.builder().region(mRegion); | ||
if(mLocalUrl != null) | ||
builder = builder.endpointOverride(URI.create(mLocalUrl)); | ||
if(StringUtils.isNotEmpty(mClientId) && | ||
StringUtils.isNotEmpty(mClientSecret)) | ||
{ | ||
AwsBasicCredentials mCredentials = AwsBasicCredentials.create(mClientId, mClientSecret); | ||
builder = builder.credentialsProvider(StaticCredentialsProvider.create(mCredentials)); | ||
} | ||
mDynamoDB = builder.build(); | ||
} | ||
|
||
//---------------------------------------------------------------------------------------------------- | ||
|
||
@Override | ||
public void close() | ||
{ | ||
mDynamoDB.close(); | ||
mDynamoDB = null; | ||
} | ||
|
||
@Override | ||
public boolean isClosed() | ||
{ | ||
return mDynamoDB != null; | ||
} | ||
|
||
//---------------------------------------------------------------------------------------------------- | ||
@Override | ||
public String getDatabaseProductName() | ||
{ | ||
return GXDYNAMODB_PRODUCT_NAME; | ||
} | ||
|
||
@Override | ||
public String getDatabaseProductVersion() | ||
{ | ||
return ""; | ||
} | ||
|
||
@Override | ||
public String getDriverName() | ||
{ | ||
return mDynamoDB.getClass().getName(); | ||
} | ||
|
||
@Override | ||
public String getDriverVersion() | ||
{ | ||
return String.format("%s/%s", mDynamoDB.serviceName(), GXDYNAMODB_VERSION); | ||
} | ||
|
||
// JDK8: | ||
@Override | ||
public void setSchema(String schema) | ||
{ | ||
throw new UnsupportedOperationException("Not supported yet."); | ||
} | ||
|
||
@Override | ||
public String getSchema() | ||
{ | ||
throw new UnsupportedOperationException("Not supported yet."); | ||
} | ||
|
||
@Override | ||
public void abort(Executor executor) | ||
{ | ||
throw new UnsupportedOperationException("Not supported yet."); | ||
} | ||
|
||
@Override | ||
public void setNetworkTimeout(Executor executor, int milliseconds) | ||
{ | ||
throw new UnsupportedOperationException("Not supported yet."); | ||
} | ||
|
||
@Override | ||
public int getNetworkTimeout() | ||
{ | ||
throw new UnsupportedOperationException("Not supported yet."); | ||
} | ||
|
||
@Override | ||
public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) | ||
{ | ||
throw new UnsupportedOperationException("Not supported yet."); | ||
} | ||
|
||
@Override | ||
public boolean generatedKeyAlwaysReturned() | ||
{ | ||
throw new UnsupportedOperationException("Not supported yet."); | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
gxdynamodb/src/main/java/com/genexus/db/dynamodb/DynamoDBDriver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package com.genexus.db.dynamodb; | ||
|
||
import java.sql.*; | ||
import java.util.Properties; | ||
import java.util.logging.Logger; | ||
|
||
public class DynamoDBDriver implements Driver | ||
{ | ||
private static final int MAJOR_VERSION = 1; | ||
private static final int MINOR_VERSION = 0; | ||
private static final String DRIVER_ID = "dynamodb:"; | ||
|
||
private static final DynamoDBDriver DYNAMODB_DRIVER; | ||
static | ||
{ | ||
DYNAMODB_DRIVER = new DynamoDBDriver(); | ||
try | ||
{ | ||
DriverManager.registerDriver(DYNAMODB_DRIVER); | ||
}catch(SQLException e) | ||
{ | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
public DynamoDBDriver() | ||
{ | ||
} | ||
|
||
@Override | ||
public Connection connect(String url, Properties info) | ||
{ | ||
if(!acceptsURL(url)) | ||
return null; | ||
return new DynamoDBConnection(url.substring(DRIVER_ID.length()), info); | ||
} | ||
|
||
@Override | ||
public boolean acceptsURL(String url) | ||
{ | ||
return url.startsWith(DRIVER_ID); | ||
} | ||
|
||
@Override | ||
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) | ||
{ | ||
return new DriverPropertyInfo[0]; | ||
} | ||
|
||
@Override | ||
public int getMajorVersion() | ||
{ | ||
return MAJOR_VERSION; | ||
} | ||
|
||
@Override | ||
public int getMinorVersion() | ||
{ | ||
return MINOR_VERSION; | ||
} | ||
|
||
@Override | ||
public boolean jdbcCompliant() | ||
{ | ||
return false; | ||
} | ||
|
||
@Override | ||
public Logger getParentLogger() | ||
{ | ||
throw new UnsupportedOperationException("Not supported yet."); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
gxdynamodb/src/main/java/com/genexus/db/dynamodb/DynamoDBErrors.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.genexus.db.dynamodb; | ||
|
||
public class DynamoDBErrors | ||
{ | ||
public static final String ValidationException = "ValidationException"; | ||
public static final CharSequence ValidationExceptionMessageKey = "The AttributeValue for a key attribute cannot contain an empty string value."; | ||
} |
Oops, something went wrong.