Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
package joliex.db;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.StringReader;
import java.math.BigDecimal;
import java.sql.Clob;
import java.sql.Connection;
Expand All @@ -40,9 +42,10 @@
// Connection Pooling
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.pool.HikariPool;

import java.util.Optional;

import java.util.Properties;
import jolie.runtime.ByteArray;
import jolie.runtime.CanUseJars;
import jolie.runtime.FaultException;
Expand Down Expand Up @@ -123,11 +126,21 @@ public void connect( Value request )
String databaseName = request.getChildren( "database" ).first().strValue();
username = request.getChildren( "username" ).first().strValue();
password = request.getChildren( "password" ).first().strValue();
String attributes = request.getFirstChild( "attributes" ).strValue();
String separator = "/";
boolean isEmbedded = false;
Optional< String > encoding = Optional
.ofNullable( request.hasChildren( "encoding" ) ? request.getFirstChild( "encoding" ).strValue() : null );

Properties attributes = new Properties();
if( request.hasChildren( "attributes" ) ) {
try {
String attributesInLines =
request.getFirstChild( "attributes" ).strValue().replaceAll( "[^\\\\];", "\n" );
attributes.load( new StringReader( attributesInLines ) );
} catch( IOException e ) {
throw new FaultException( "InvalidDriver", "Invalid driver attributes syntax" );
}
}

try {
if( driverClass == null ) {
switch( driver ) {
Expand All @@ -142,7 +155,6 @@ public void connect( Value request )
break;
case "sqlite":
driverClass = "org.sqlite.JDBC";
isEmbedded = true;
break;
case "sqlserver":
driverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
Expand All @@ -154,12 +166,8 @@ public void connect( Value request )
break;
case "derby_embedded":
driverClass = "org.apache.derby.jdbc.EmbeddedDriver";
isEmbedded = true;
driver = "derby";
break;
case "hsqldb_embedded":
isEmbedded = true;
driver = "hsqldb";
case "hsqldb_hsql":
case "hsqldb_hsqls":
case "hsqldb_http":
Expand All @@ -175,12 +183,12 @@ public void connect( Value request )
}
Class.forName( driverClass );

if( isEmbedded ) {
if( driver.endsWith( "_embedded" ) || "sqlite".equals( driver ) ) {
driver = driver.split( "_", 2 )[ 0 ]; // "derby_embedded" => "derby", "sqlite" => "sqlite"
connectionString = "jdbc:" + driver + ":" + databaseName;
if( !attributes.isEmpty() ) {
connectionString += ";" + attributes;
}
connectionPool = _createDataSource( request.getFirstChild( "connectionPoolConfig" ), connectionString );

connectionPool =
_createDataSource( request.getFirstChild( "connectionPoolConfig" ), connectionString, attributes );
if( !"hsqldb".equals( driver ) ) { // driver == sqlite || driver == derby_embedded
connectionPool.setUsername( null );
connectionPool.setPassword( null );
Expand All @@ -194,16 +202,21 @@ public void connect( Value request )
+ databaseName;
}
if( encoding.isPresent() ) {
connectionString += "?characterEncoding=" + encoding.get();
attributes.setProperty( "characterEncoding", encoding.get() );
}
connectionPool = _createDataSource( request.getFirstChild( "connectionPoolConfig" ), connectionString );
connectionPool =
_createDataSource( request.getFirstChild( "connectionPoolConfig" ), connectionString, attributes );
}

interpreter().cleaner().register( this, () -> {
_closeConnectionPool();
} );
} catch( ClassNotFoundException e ) {
throw new FaultException( "DriverClassNotFound", e );
} catch( HikariPool.PoolInitializationException e ) {
throw e.getCause() instanceof SQLException
? createFaultException( ((SQLException) e.getCause()) )
: new FaultException( "InvalidDriver", e );
}
}

Expand All @@ -228,7 +241,7 @@ public void checkConnection()
try( Connection con = connectionPool.getConnection() ) { // HikariCP validates connections before providing
// them
} catch( SQLException e ) {
createFaultException( e );
throw createFaultException( e );
}
}
}
Expand Down Expand Up @@ -583,7 +596,7 @@ public void commitTx( Value request ) throws FaultException {
try {
tx.commit();
} catch( SQLException e ) {
createFaultException( e );
throw createFaultException( e );
} finally {
_closeTransaction( tx );
}
Expand Down Expand Up @@ -625,19 +638,19 @@ private void _closeConnectionPool() {
connectionPool.close();
}

private HikariDataSource _createDataSource( Value providedConfig, String connectionString ) {
private HikariDataSource _createDataSource( Value providedConfig, String connectionString, Properties attributes ) {
HikariConfig config = new HikariConfig();
config.setUsername( username );
config.setPassword( password );
config.setDriverClassName( driverClass );
config.setJdbcUrl( connectionString );

_setUserProvidedConfig( config, providedConfig );
_setUserProvidedConfig( config, providedConfig, attributes );

return new HikariDataSource( config );
}

private void _setUserProvidedConfig( HikariConfig config, Value providedConfig ) {
private void _setUserProvidedConfig( HikariConfig config, Value providedConfig, Properties attributes ) {
if( providedConfig.hasChildren() ) {
if( providedConfig.hasChildren( "connectionTimeout" ) ) {
config.setConnectionTimeout( providedConfig.getFirstChild( "connectionTimeout" ).longValue() );
Expand Down Expand Up @@ -689,5 +702,9 @@ private void _setUserProvidedConfig( HikariConfig config, Value providedConfig )
.setValidationTimeout( providedConfig.getFirstChild( "validationTimeout" ).longValue() );
}
}

for( String propName : attributes.stringPropertyNames() ) {
config.addDataSourceProperty( propName, attributes.getProperty( propName ) );
}
}
}
115 changes: 115 additions & 0 deletions test/library/embedded-database.ol
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright (C) 2024 Claudio Guidi <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/

from ..test-unit import TestUnitInterface
from database import Database
from runtime import Runtime
from string_utils import StringUtils
from file import File
from zip-utils import ZipUtils

interface ApacheDerbyDownloadInterface {
RequestResponse:
downloadDerby
}

service Main {

embed Database as Database
embed Runtime as Runtime
embed StringUtils as StringUtils
embed File as File
embed ZipUtils as ZipUtils

inputPort TestUnitInput {
location: "local"
interfaces: TestUnitInterface
}

define initDatabase
{
scope( init_db ) {
install( SQLException => throw( TestFailed, init_db.SQLException.stackTrace ) )
i = 0
q.statement[i++] = "create table test (
name varchar(128) not null
)"
executeTransaction@Database( q )()
undef( q )
}
}

define connect_db {
connectionInfo << {
host = ""
driver = "derby_embedded"
port = 0
database = "./data"
username = ""
password = ""
};
connect@Database( connectionInfo )()
}

main {
test()() {
loadLibrary@Runtime( "./library/private/derby.jar" )()

scope( ConnectionScope ) {
install( IOException => throw( TestFailed, ConnectionScope.IOException.stackTrace ) )
install( ConnectionError =>
connectionInfo.attributes = "create=true"
connect@Database( connectionInfo )()
initDatabase
connect_db
)
install( SQLException =>
if ( ConnectionScope.SQLException.SQLState == "XJ004" && ConnectionScope.SQLException.errorCode == 40000 ) {
connectionInfo.attributes = "create=true"
connect@Database( connectionInfo )()
initDatabase
connect_db
} else {
valueToPrettyString@StringUtils( ConnectionScope.SQLException )( error )
throw( TestFailed, "SQLEXception critical error" )
}
)

connect_db
}


q = "INSERT INTO test (name) VALUES ('test')"
update@Database( q )()

q = "SELECT * FROM test"
query@Database( q )( result )
if ( #result.row != 1 ) {
throw( TestFailed, "Wrong number of rows" )
}
if ( result.row[ 0 ].NAME != "test" ) {
throw( TestFailed, "wrong reading from database" )
}
// delete@File( "derby.jar" )()
delete@File( "derby.log" )()
deleteDir@File("./data")()
deleteDir@File("./unzip")()
}
}
}
31 changes: 31 additions & 0 deletions test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,31 @@
</arguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>copy-derby</id>
<phase>process-test-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.14.2.0</version>
<destFileName>derby.jar</destFileName>
<outputDirectory>${test.dir}/library/private</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
Expand Down Expand Up @@ -133,6 +158,12 @@
<version>${jolie.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.14.2.0</version>
<scope>test</scope>
</dependency>

<!-- Extensions -->
<dependency>
Expand Down
Loading