diff --git a/src/main/java/org/polypheny/simpleclient/cli/MultimediaCommand.java b/src/main/java/org/polypheny/simpleclient/cli/MultimediaCommand.java index 5601a3e2..eb151c02 100644 --- a/src/main/java/org/polypheny/simpleclient/cli/MultimediaCommand.java +++ b/src/main/java/org/polypheny/simpleclient/cli/MultimediaCommand.java @@ -35,6 +35,7 @@ import lombok.extern.slf4j.Slf4j; import org.polypheny.simpleclient.executor.Executor.ExecutorFactory; import org.polypheny.simpleclient.executor.PolyphenyDbJdbcExecutor.PolyphenyDbJdbcExecutorFactory; +import org.polypheny.simpleclient.executor.PolyphenyDbRestExecutor.PolyphenyDbRestExecutorFactory; import org.polypheny.simpleclient.main.Multimedia; @@ -52,8 +53,8 @@ public class MultimediaCommand implements CliRunnable { @Option(name = { "-pdb", "--polyphenydb" }, title = "IP or Hostname", arity = 1, description = "IP or Hostname of the Polypheny-DB server (default: 127.0.0.1).") public static String polyphenyDbHost = "127.0.0.1"; - //@Option(name = { "--rest" }, arity = 0, description = "Use Polypheny-DB REST interface instead of the JDBC interface (default: false).") - //public static boolean restInterface = false; + @Option(name = { "--rest" }, arity = 0, description = "Use Polypheny-DB REST interface instead of the JDBC interface (default: false).") + public static boolean restInterface = false; @Option(name = { "--writeCSV" }, arity = 0, description = "Write a CSV file containing execution times for all executed queries (default: false).") public boolean writeCsv = false; @@ -79,12 +80,11 @@ public int run() { } ExecutorFactory executorFactory; - /*if ( restInterface ) { + if ( restInterface ) { executorFactory = new PolyphenyDbRestExecutorFactory( polyphenyDbHost ); } else { - executorFactory = new PolyphenyDbJdbcExecutorFactory( polyphenyDbHost ); - }*/ - executorFactory = new PolyphenyDbJdbcExecutorFactory( polyphenyDbHost, true ); + executorFactory = new PolyphenyDbJdbcExecutorFactory( polyphenyDbHost, true ); + } if ( args.get( 0 ).equalsIgnoreCase( "data" ) ) { Multimedia.data( executorFactory, multiplier, true ); diff --git a/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java b/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java index ee4c3d77..4b77f0f6 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/JdbcExecutor.java @@ -26,7 +26,11 @@ package org.polypheny.simpleclient.executor; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.file.Files; import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -34,6 +38,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -74,8 +79,9 @@ public JdbcExecutor( CsvWriter csvWriter, boolean prepareStatements ) { @Override public long executeQuery( Query query ) throws ExecutorException { try { - log.debug( query.getSql() ); + log.debug( query.getSql().substring( 0, Math.min( 500, query.getSql().length() ) ) ); + ArrayList files = new ArrayList<>(); long start = System.nanoTime(); if ( prepareStatements && query.getParameterizedSqlQuery() != null ) { @@ -109,6 +115,11 @@ public long executeQuery( Query query ) throws ExecutorException { case BYTE_ARRAY: preparedStatement.setBytes( entry.getKey(), (byte[]) entry.getValue().right ); break; + case FILE: + File f = (File) entry.getValue().right; + files.add( f ); + preparedStatement.setBinaryStream( entry.getKey(), new FileInputStream( f ) ); + break; } } if ( query.isExpectResultSet() ) { @@ -131,11 +142,12 @@ public long executeQuery( Query query ) throws ExecutorException { } long time = System.nanoTime() - start; + files.forEach( File::delete ); if ( csvWriter != null ) { csvWriter.appendToCsv( query.getSql(), time ); } return time; - } catch ( SQLException e ) { + } catch ( SQLException | FileNotFoundException e ) { throw new ExecutorException( e ); } } @@ -144,7 +156,7 @@ public long executeQuery( Query query ) throws ExecutorException { @Override public long executeQueryAndGetNumber( Query query ) throws ExecutorException { try { - log.debug( query.getSql() ); + //log.debug( query.getSql() ); ResultSet resultSet = executeStatement.executeQuery( query.getSql() ); @@ -216,6 +228,7 @@ public void executeInsertList( List queryList, AbstractConfig c protected void executeInsertListAsPreparedBatch( List queryList ) throws ExecutorException { try { PreparedStatement preparedStatement = connection.prepareStatement( queryList.get( 0 ).getParameterizedSqlQuery() ); + ArrayList files = new ArrayList<>(); for ( BatchableInsert insert : queryList ) { Map> data = insert.getParameterValues(); for ( Map.Entry> entry : data.entrySet() ) { @@ -241,13 +254,21 @@ protected void executeInsertListAsPreparedBatch( List queryList case BYTE_ARRAY: preparedStatement.setBytes( entry.getKey(), (byte[]) entry.getValue().right ); break; + case FILE: + File f = (File) entry.getValue().right; + byte[] b = Files.readAllBytes( f.toPath() ); + preparedStatement.setBytes( entry.getKey(), b ); + break; } } preparedStatement.addBatch(); } preparedStatement.executeBatch(); preparedStatement.close(); - } catch ( SQLException e ) { + files.forEach( File::delete ); + } catch ( SQLException | FileNotFoundException e ) { + throw new ExecutorException( e ); + } catch ( IOException e ) { throw new ExecutorException( e ); } } diff --git a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbRestExecutor.java b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbRestExecutor.java index a036b3a8..2add8952 100644 --- a/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbRestExecutor.java +++ b/src/main/java/org/polypheny/simpleclient/executor/PolyphenyDbRestExecutor.java @@ -1,5 +1,6 @@ package org.polypheny.simpleclient.executor; + import com.google.gson.JsonObject; import java.io.IOException; import java.util.ArrayList; @@ -15,6 +16,7 @@ import org.polypheny.simpleclient.executor.PolyphenyDbJdbcExecutor.PolyphenyDbJdbcExecutorFactory; import org.polypheny.simpleclient.main.CsvWriter; import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.MultipartInsert; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.RawQuery; import org.polypheny.simpleclient.scenario.AbstractConfig; @@ -45,6 +47,12 @@ public void reset() throws ExecutorException { @Override public long executeQuery( Query query ) throws ExecutorException { + //query.debug(); + if ( query instanceof MultipartInsert ) { + long l = executeQuery( new RawQuery( null, ((MultipartInsert) query).buildMultipartInsert(), query.isExpectResultSet() ) ); + ((MultipartInsert) query).cleanup(); + return l; + } long time; if ( query.getRest() != null ) { HttpRequest request = query.getRest(); @@ -55,7 +63,7 @@ public long executeQuery( Query query ) throws ExecutorException { log.debug( request.getUrl() ); try { long start = System.nanoTime(); - HttpResponse result = request.asJson(); + @SuppressWarnings("rawtypes") HttpResponse result = request.asBytes(); if ( !result.isSuccess() ) { throw new ExecutorException( "Error while executing REST query. Message: " + result.getStatusText() + " | URL: " + request.getUrl() ); } @@ -68,7 +76,7 @@ public long executeQuery( Query query ) throws ExecutorException { } } else { // There is no REST expression available for this query. Executing SQL expression via JDBC. - log.warn( query.getSql() ); + //log.warn( query.getSql() ); JdbcExecutor executor = null; try { executor = jdbcExecutorFactory.createExecutorInstance( csvWriter ); @@ -89,6 +97,12 @@ public long executeQuery( Query query ) throws ExecutorException { @Override public long executeQueryAndGetNumber( Query query ) throws ExecutorException { + query.debug(); + if ( query instanceof MultipartInsert ) { + long l = executeQuery( new RawQuery( null, ((MultipartInsert) query).buildMultipartInsert(), query.isExpectResultSet() ) ); + ((MultipartInsert) query).cleanup(); + return l; + } if ( query.getRest() != null ) { HttpRequest request = query.getRest(); request.basicAuth( "pa", "" ); @@ -120,7 +134,7 @@ public long executeQueryAndGetNumber( Query query ) throws ExecutorException { } } else { // There is no REST expression available for this query. Executing SQL expression via JDBC. - log.warn( query.getSql() ); + log.warn( query.getSql().substring( 0, Math.min( 500, query.getSql().length() ) ) ); JdbcExecutor executor = null; try { executor = jdbcExecutorFactory.createExecutorInstance( csvWriter ); @@ -157,6 +171,12 @@ public void executeInsertList( List batchList, AbstractConfig c String currentTable = null; List rows = new ArrayList<>(); for ( BatchableInsert query : batchList ) { + query.debug(); + if ( query instanceof MultipartInsert ) { + executeQuery( new RawQuery( null, ((MultipartInsert) query).buildMultipartInsert(), query.isExpectResultSet() ) ); + ((MultipartInsert) query).cleanup(); + continue; + } if ( currentTable == null ) { currentTable = query.getTable(); } diff --git a/src/main/java/org/polypheny/simpleclient/query/MultipartInsert.java b/src/main/java/org/polypheny/simpleclient/query/MultipartInsert.java new file mode 100644 index 00000000..d83af8f5 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/query/MultipartInsert.java @@ -0,0 +1,76 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Databases and Information Systems Research Group, University of Basel, Switzerland + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.query; + + +import com.google.gson.JsonArray; +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import kong.unirest.HttpRequest; +import kong.unirest.MultipartBody; +import kong.unirest.Unirest; + + +public abstract class MultipartInsert extends BatchableInsert { + + Map files = new HashMap<>(); + + public MultipartInsert( boolean expectResult ) { + super( expectResult ); + } + + public void setFile( String column, File f ) { + files.put( column, f ); + } + + public abstract Map getRestParameters(); + + public HttpRequest buildMultipartInsert() { + MultipartBody body = Unirest.post( "{protocol}://{host}:{port}/restapi/v1/multipart" ).multiPartContent(); + body.field( "resName", getTable() ); + if ( getRestRowExpression() != null ) { + JsonArray jsonArray = new JsonArray(); + jsonArray.add( getRestRowExpression() ); + body.field( "data", jsonArray.toString() ); + } + if ( getRestParameters() != null ) { + for ( Entry entry : getRestParameters().entrySet() ) { + body.field( entry.getKey(), entry.getValue() ); + } + } + for ( Entry entry : files.entrySet() ) { + body.field( entry.getKey(), entry.getValue() ); + } + return body; + } + + public void cleanup() { + files.forEach( ( key, file ) -> file.delete() ); + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/query/Query.java b/src/main/java/org/polypheny/simpleclient/query/Query.java index c21bc324..d8fa7d88 100644 --- a/src/main/java/org/polypheny/simpleclient/query/Query.java +++ b/src/main/java/org/polypheny/simpleclient/query/Query.java @@ -34,9 +34,11 @@ import kong.unirest.RequestBodyEntity; import kong.unirest.Unirest; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.ImmutablePair; +@Slf4j public abstract class Query { @Getter @@ -48,7 +50,7 @@ public Query( boolean expectResultSet ) { } - public enum DataTypes {INTEGER, VARCHAR, TIMESTAMP, DATE, ARRAY_INT, ARRAY_REAL, BYTE_ARRAY} + public enum DataTypes {INTEGER, VARCHAR, TIMESTAMP, DATE, ARRAY_INT, ARRAY_REAL, BYTE_ARRAY, FILE} public abstract String getSql(); @@ -94,4 +96,16 @@ public static HttpRequest buildRestUpdate( String table, JsonObject set, Map< return request; } + public void debug() { + String parametrizedQuery = getParameterizedSqlQuery(); + if ( parametrizedQuery != null ) { + log.debug( parametrizedQuery.substring( 0, Math.min( 500, parametrizedQuery.length() ) ) ); + } else { + String sql = getSql(); + if ( sql != null ) { + log.debug( sql.substring( 0, Math.min( 500, sql.length() ) ) ); + } + } + } + } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/DataGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/DataGenerator.java index ded6096f..0c52c9c6 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/DataGenerator.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/DataGenerator.java @@ -26,9 +26,12 @@ package org.polypheny.simpleclient.scenario.multimedia; +import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import lombok.extern.slf4j.Slf4j; import org.polypheny.simpleclient.executor.Executor; @@ -52,6 +55,7 @@ public class DataGenerator { private final ProgressReporter progressReporter; private final List batchList; + Map> queryTimes = new HashMap<>(); private boolean aborted; @@ -66,7 +70,7 @@ public class DataGenerator { } - void generateUsers() throws ExecutorException { + Map> generateUsers() throws ExecutorException { int numberOfUsers = config.numberOfUsers; int mod = numberOfUsers / progressReporter.base; InsertUser insertUser = new InsertUser( config.imgSize ); @@ -116,6 +120,7 @@ void generateUsers() throws ExecutorException { } executeInsertList(); } + return queryTimes; } @@ -128,8 +133,28 @@ private void addToInsertList( BatchableInsert query ) throws ExecutorException { private void executeInsertList() throws ExecutorException { + if ( batchList.size() == 0 ) { + return; + } + long startTime = System.nanoTime(); theExecutor.executeInsertList( batchList, config ); theExecutor.executeCommit(); + long executionTime = System.nanoTime() - startTime; + ArrayList executionTimes = new ArrayList<>(); + //add execution n times to get the right average later on + for ( int i = 0; i < batchList.size(); i++ ) { + executionTimes.add( executionTime ); + } + //the batchList contains only queries of one type + String sql = batchList.get( 0 ).getParameterizedSqlQuery(); + if ( sql == null ) { + sql = batchList.get( 0 ).getSql(); + sql = sql.substring( 0, Math.min( 500, sql.length() ) ); + } + if ( !queryTimes.containsKey( sql ) ) { + queryTimes.put( batchList.get( 0 ).getParameterizedSqlQuery(), new ArrayList<>() ); + } + queryTimes.get( batchList.get( 0 ).getParameterizedSqlQuery() ).addAll( executionTimes ); batchList.clear(); } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MediaGenerator.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MediaGenerator.java index 2f25fcc3..47e10f1c 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MediaGenerator.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MediaGenerator.java @@ -101,7 +101,7 @@ public static File generateRandomWav( int sizeKB ) { File out = randomFile( "wav" ); //see https://www.programcreek.com/java-api-examples/?class=javax.sound.sampled.AudioSystem&method=write AudioFormat format = new AudioFormat( PCM_SIGNED, 44100, 8, 1, 1, 44100, false ); - AudioInputStream ais = new AudioInputStream( new RandomInputStream( sizeKB * 1000 ), format, sizeKB * 1000 ); + AudioInputStream ais = new AudioInputStream( new RandomInputStream( sizeKB * 1000 ), format, sizeKB * 1000L ); try { FileUtils.copyInputStreamToFile( ais, out ); } catch ( IOException e ) { diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MultimediaBench.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MultimediaBench.java index 5fa72834..1e2d1fff 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MultimediaBench.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MultimediaBench.java @@ -58,7 +58,9 @@ import org.polypheny.simpleclient.scenario.multimedia.queryBuilder.CreateTable; import org.polypheny.simpleclient.scenario.multimedia.queryBuilder.DeleteRandomTimeline; import org.polypheny.simpleclient.scenario.multimedia.queryBuilder.InsertRandomTimeline; -import org.polypheny.simpleclient.scenario.multimedia.queryBuilder.SelectRandomAlbum; +import org.polypheny.simpleclient.scenario.multimedia.queryBuilder.SelectMediaWhereAlbum; +import org.polypheny.simpleclient.scenario.multimedia.queryBuilder.SelectMultipleProfilePics; +import org.polypheny.simpleclient.scenario.multimedia.queryBuilder.SelectRandomProfilePic; import org.polypheny.simpleclient.scenario.multimedia.queryBuilder.SelectRandomTimeline; import org.polypheny.simpleclient.scenario.multimedia.queryBuilder.SelectRandomUser; @@ -74,7 +76,8 @@ public class MultimediaBench extends Scenario { public MultimediaBench( Executor.ExecutorFactory executorFactory, MultimediaConfig config, boolean commitAfterEveryQuery, boolean dumpQueryList ) { - super( executorFactory, commitAfterEveryQuery, dumpQueryList ); + //never dump mm queries, because the dumps can get very large for large binary inserts + super( executorFactory, commitAfterEveryQuery, false ); this.config = config; measuredTimes = Collections.synchronizedList( new LinkedList<>() ); @@ -121,23 +124,35 @@ public void createSchema( boolean includingKeys ) { try { executor = executorFactory.createExecutorInstance(); - executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"users\" (\"id\" INTEGER NOT NULL, \"firstName\" VARCHAR(1000) NOT NULL, \"lastName\" VARCHAR(1000) NOT NULL, \"email\" VARCHAR(1000) NOT NULL, \"password\" VARCHAR(1000) NOT NULL, \"profile_pic\" IMAGE NOT NULL, PRIMARY KEY(\"id\"))" )).getNewQuery() ); - executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"album\" (\"id\" INTEGER NOT NULL, \"user_id\" INTEGER NOT NULL, \"name\" VARCHAR(200) NOT NULL, PRIMARY KEY(\"id\"))" )).getNewQuery() ); - executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"media\" (\"id\" INTEGER NOT NULL, \"timestamp\" TIMESTAMP NOT NULL, \"album_id\" INTEGER NOT NULL, \"img\" IMAGE, \"video\" VIDEO, \"sound\" SOUND, PRIMARY KEY(\"id\"))" )).getNewQuery() ); - executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"timeline\" (\"id\" INTEGER NOT NULL, \"timestamp\" TIMESTAMP NOT NULL, \"user_id\" INTEGER NOT NULL, \"message\" VARCHAR(2000), \"img\" IMAGE, \"video\" VIDEO, \"sound\" SOUND, PRIMARY KEY(\"id\"))" )).getNewQuery() ); - executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"followers\" (\"user_id\" INTEGER NOT NULL,\"friend_id\" INTEGER NOT NULL, PRIMARY KEY(\"user_id\", \"friend_id\"))" )).getNewQuery() ); + String onStore = String.format( " ON STORE \"%s\"", config.dataStore ); + executor.executeQuery( (new CreateTable( "ALTER CONFIG 'validation/validateMultimediaContentType' SET FALSE" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"users\" (\"id\" INTEGER NOT NULL, \"firstName\" VARCHAR(1000) NOT NULL, \"lastName\" VARCHAR(1000) NOT NULL, \"email\" VARCHAR(1000) NOT NULL, \"password\" VARCHAR(1000) NOT NULL, \"profile_pic\" IMAGE NOT NULL, PRIMARY KEY(\"id\"))" + onStore )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"album\" (\"id\" INTEGER NOT NULL, \"user_id\" INTEGER NOT NULL, \"name\" VARCHAR(200) NOT NULL, PRIMARY KEY(\"id\"))" + onStore )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"media\" (\"id\" INTEGER NOT NULL, \"timestamp\" TIMESTAMP NOT NULL, \"album_id\" INTEGER NOT NULL, \"img\" IMAGE, \"video\" VIDEO, \"sound\" SOUND, PRIMARY KEY(\"id\"))" + onStore )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"timeline\" (\"id\" INTEGER NOT NULL, \"timestamp\" TIMESTAMP NOT NULL, \"user_id\" INTEGER NOT NULL, \"message\" VARCHAR(2000), \"img\" IMAGE, \"video\" VIDEO, \"sound\" SOUND, PRIMARY KEY(\"id\"))" + onStore )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "CREATE TABLE IF NOT EXISTS \"followers\" (\"user_id\" INTEGER NOT NULL,\"friend_id\" INTEGER NOT NULL, PRIMARY KEY(\"user_id\", \"friend_id\"))" + onStore )).getNewQuery() ); executor.executeQuery( (new CreateTable( "TRUNCATE TABLE \"users\"" )).getNewQuery() ); executor.executeQuery( (new CreateTable( "TRUNCATE TABLE \"album\"" )).getNewQuery() ); executor.executeQuery( (new CreateTable( "TRUNCATE TABLE \"media\"" )).getNewQuery() ); executor.executeQuery( (new CreateTable( "TRUNCATE TABLE \"timeline\"" )).getNewQuery() ); executor.executeQuery( (new CreateTable( "TRUNCATE TABLE \"followers\"" )).getNewQuery() ); + if ( !config.multimediaStore.equals( "same" ) && !config.dataStore.equals( config.multimediaStore ) ) { + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"users\" ADD PLACEMENT (\"profile_pic\") ON STORE \"" + config.multimediaStore + "\"" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"media\" ADD PLACEMENT (\"img\", \"video\", \"sound\") ON STORE \"" + config.multimediaStore + "\"" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"timeline\" ADD PLACEMENT (\"img\", \"video\", \"sound\") ON STORE \"" + config.multimediaStore + "\"" )).getNewQuery() ); + + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"users\" MODIFY PLACEMENT (\"id\", \"firstName\", \"lastName\", \"email\", \"password\") ON STORE \"" + config.dataStore + "\"" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"media\" MODIFY PLACEMENT (\"id\", \"timestamp\", \"album_id\") ON STORE \"" + config.dataStore + "\"" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"timeline\" MODIFY PLACEMENT (\"id\", \"timestamp\", \"user_id\", \"message\") ON STORE \"" + config.dataStore + "\"" )).getNewQuery() ); + } + if ( includingKeys ) { - executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"album\" ADD CONSTRAINT \"fk1\" FOREIGN KEY(\"user_id\") REFERENCES \"users\"(\"id\") ON UPDATE CASCADE ON DELETE CASCADE" )).getNewQuery() ); - executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"media\" ADD CONSTRAINT \"fk2\" FOREIGN KEY(\"album_id\") REFERENCES \"album\"(\"id\") ON UPDATE CASCADE ON DELETE CASCADE" )).getNewQuery() ); - executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"timeline\" ADD CONSTRAINT \"fk3\" FOREIGN KEY(\"user_id\") REFERENCES \"users\"(\"id\") ON UPDATE CASCADE ON DELETE CASCADE" )).getNewQuery() ); - executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"followers\" ADD CONSTRAINT \"fk4\" FOREIGN KEY(\"user_id\") REFERENCES \"users\"(\"id\") ON UPDATE CASCADE ON DELETE CASCADE" )).getNewQuery() ); - executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"followers\" ADD CONSTRAINT \"fk5\" FOREIGN KEY(\"friend_id\") REFERENCES \"users\"(\"id\") ON UPDATE CASCADE ON DELETE CASCADE" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"album\" ADD CONSTRAINT \"fk1\" FOREIGN KEY(\"user_id\") REFERENCES \"users\"(\"id\") ON UPDATE RESTRICT ON DELETE RESTRICT" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"media\" ADD CONSTRAINT \"fk2\" FOREIGN KEY(\"album_id\") REFERENCES \"album\"(\"id\") ON UPDATE RESTRICT ON DELETE RESTRICT" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"timeline\" ADD CONSTRAINT \"fk3\" FOREIGN KEY(\"user_id\") REFERENCES \"users\"(\"id\") ON UPDATE RESTRICT ON DELETE RESTRICT" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"followers\" ADD CONSTRAINT \"fk4\" FOREIGN KEY(\"user_id\") REFERENCES \"users\"(\"id\") ON UPDATE RESTRICT ON DELETE RESTRICT" )).getNewQuery() ); + executor.executeQuery( (new CreateTable( "ALTER TABLE public.\"followers\" ADD CONSTRAINT \"fk5\" FOREIGN KEY(\"friend_id\") REFERENCES \"users\"(\"id\") ON UPDATE RESTRICT ON DELETE RESTRICT" )).getNewQuery() ); } } catch ( ExecutorException e ) { throw new RuntimeException( "Exception while creating schema", e ); @@ -154,7 +169,13 @@ public void generateData( ProgressReporter progressReporter ) { DataGenerator dataGenerator = new DataGenerator( executor1, config, progressReporter ); try { - dataGenerator.generateUsers(); + Map> executionTimes = dataGenerator.generateUsers(); + executionTimes.forEach( ( s, l ) -> { + measuredTimes.addAll( l ); + int id = queryTypes.size() + 1; + queryTypes.put( id, s ); + measuredTimePerQueryType.put( id, l ); + } ); } catch ( ExecutorException e ) { throw new RuntimeException( "Exception while generating data", e ); } finally { @@ -168,15 +189,18 @@ public long execute( ProgressReporter progressReporter, CsvWriter csvWriter, Fil log.info( "Preparing query list for the benchmark..." ); List queryList = new Vector<>(); - addNumberOfTimes( queryList, new SelectRandomUser( config.numberOfUsers ), config.read ); - addNumberOfTimes( queryList, new SelectRandomAlbum( config.numberOfUsers ), config.read ); - addNumberOfTimes( queryList, new SelectRandomTimeline( config.numberOfUsers ), config.read ); - addNumberOfTimes( queryList, new DeleteRandomTimeline( config.numberOfUsers * config.postsPerUser ), config.write ); - addNumberOfTimes( queryList, new InsertRandomTimeline( config.numberOfUsers, config.imgSize, config.numberOfFrames, config.fileSizeKB ), config.write ); + addNumberOfTimes( queryList, new SelectRandomUser( config.numberOfUsers ), config.numberOfSelectUserQueries ); + addNumberOfTimes( queryList, new SelectRandomProfilePic( config.numberOfUsers ), config.numberOfSelectProfilePicQueries ); + addNumberOfTimes( queryList, new SelectMultipleProfilePics( config.numberOfUsers ), config.numberOfSelectProfilePicsQueries ); + addNumberOfTimes( queryList, new SelectMediaWhereAlbum( config.numberOfUsers ), config.numberOfSelectMediaQueries );//numberOfAlbums = numberOfUsers (1 album per user) + addNumberOfTimes( queryList, new SelectRandomTimeline( config.numberOfUsers * config.postsPerUser ), config.numberOfSelectTimelineQueries ); + addNumberOfTimes( queryList, new DeleteRandomTimeline( config.numberOfUsers * config.postsPerUser ), config.numberOfDeleteTimelineQueries ); + addNumberOfTimes( queryList, new InsertRandomTimeline( config.numberOfUsers, config.postsPerUser, config.imgSize, config.numberOfFrames, config.fileSizeKB, false ), config.numberOfInsertTimelineQueries ); Collections.shuffle( queryList ); // This dumps the sql queries independent of the selected interface + // always false for the MultimediaBench if ( outputDirectory != null && dumpQueryList ) { log.info( "Dump query list..." ); try { @@ -244,10 +268,12 @@ public void warmUp( ProgressReporter progressReporter, int iterations ) { executor = executorFactory.createExecutorInstance(); if ( config.numberOfUsers > 0 ) { executor.executeQuery( new SelectRandomUser( config.numberOfUsers ).getNewQuery() ); - executor.executeQuery( new SelectRandomAlbum( config.numberOfUsers ).getNewQuery() ); - executor.executeQuery( new SelectRandomTimeline( config.numberOfUsers ).getNewQuery() ); + executor.executeQuery( new SelectRandomProfilePic( config.numberOfUsers ).getNewQuery() ); + executor.executeQuery( new SelectMultipleProfilePics( config.numberOfUsers ).getNewQuery() ); + executor.executeQuery( new SelectMediaWhereAlbum( config.numberOfUsers ).getNewQuery() );//numberOfAlbums = numberOfUsers (1 album per user) + executor.executeQuery( new SelectRandomTimeline( config.numberOfUsers * config.postsPerUser ).getNewQuery() ); executor.executeQuery( new DeleteRandomTimeline( config.numberOfUsers * config.postsPerUser ).getNewQuery() ); - executor.executeQuery( new InsertRandomTimeline( config.numberOfUsers, config.imgSize, config.numberOfFrames, config.fileSizeKB ).getNewQuery() ); + executor.executeQuery( new InsertRandomTimeline( config.numberOfUsers, config.postsPerUser, config.imgSize, config.numberOfFrames, config.fileSizeKB, true ).getNewQuery() ); } } catch ( ExecutorException e ) { throw new RuntimeException( "Error while executing warm-up queries", e ); @@ -406,7 +432,9 @@ public int getNumberOfInsertThreads() { private void addNumberOfTimes( List list, QueryBuilder queryBuilder, int numberOfTimes ) { int id = queryTypes.size() + 1; - queryTypes.put( id, queryBuilder.getNewQuery().getSql() ); + String sql = queryBuilder.getNewQuery().getSql(); + //cut long queries with binary data + queryTypes.put( id, sql.substring( 0, Math.min( 500, sql.length() ) ) ); measuredTimePerQueryType.put( id, Collections.synchronizedList( new LinkedList<>() ) ); for ( int i = 0; i < numberOfTimes; i++ ) { list.add( new QueryListEntry( queryBuilder.getNewQuery(), id ) ); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MultimediaConfig.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MultimediaConfig.java index a32a910a..085cbe63 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MultimediaConfig.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/MultimediaConfig.java @@ -35,6 +35,8 @@ @Slf4j public class MultimediaConfig extends AbstractConfig { + public final String dataStore; + public final String multimediaStore; public final int numberOfUsers; public final int postsPerUser; public final int numberOfFriends; @@ -42,14 +44,20 @@ public class MultimediaConfig extends AbstractConfig { public final int imgSize; public final int numberOfFrames; public final int fileSizeKB; + public final int numberOfSelectUserQueries; + public final int numberOfSelectProfilePicQueries; + public final int numberOfSelectProfilePicsQueries; + public final int numberOfSelectMediaQueries; + public final int numberOfSelectTimelineQueries; + public final int numberOfDeleteTimelineQueries; + public final int numberOfInsertTimelineQueries; + public final int maxBatchSize; - public final int read; - public final int write; public MultimediaConfig( Properties properties, int multiplier ) { - super( "multimedia", "polypheny" ); + super( "multimedia", "polypheny-rest" ); pdbBranch = null; puiBranch = null; @@ -58,18 +66,28 @@ public MultimediaConfig( Properties properties, int multiplier ) { router = "icarus"; planAndImplementationCaching = "Both"; - dataStores.add( "file" ); progressReportBase = getIntProperty( properties, "progressReportBase" ); numberOfThreads = getIntProperty( properties, "numberOfThreads" ); numberOfWarmUpIterations = getIntProperty( properties, "numberOfWarmUpIterations" ); + dataStore = getStringProperty( properties, "dataStore" ); + multimediaStore = getStringProperty( properties, "multimediaStore" ); + dataStores.add( dataStore ); + if ( !multimediaStore.equals( "same" ) ) { + dataStores.add( multimediaStore ); + } numberOfUsers = getIntProperty( properties, "numberOfUsers" ) * multiplier; albumSize = getIntProperty( properties, "albumSize" ); postsPerUser = getIntProperty( properties, "postsPerUser" ); numberOfFriends = getIntProperty( properties, "numberOfFriends" ); - read = getIntProperty( properties, "read" ); - write = getIntProperty( properties, "write" ); + numberOfSelectUserQueries = getIntProperty( properties, "numberOfSelectUserQueries" ); + numberOfSelectProfilePicQueries = getIntProperty( properties, "numberOfSelectProfilePicQueries" ); + numberOfSelectProfilePicsQueries = getIntProperty( properties, "numberOfSelectProfilePicsQueries" ); + numberOfSelectMediaQueries = getIntProperty( properties, "numberOfSelectMediaQueries" ); + numberOfSelectTimelineQueries = getIntProperty( properties, "numberOfSelectTimelineQueries" ); + numberOfDeleteTimelineQueries = getIntProperty( properties, "numberOfDeleteTimelineQueries" ); + numberOfInsertTimelineQueries = getIntProperty( properties, "numberOfInsertTimelineQueries" ); imgSize = getIntProperty( properties, "imgSize" ); numberOfFrames = getIntProperty( properties, "numberOfFrames" ); @@ -86,7 +104,6 @@ public MultimediaConfig( Map cdl ) { resetCatalog = Boolean.parseBoolean( cdl.get( "resetCatalog" ) ); memoryCatalog = Boolean.parseBoolean( cdl.get( "memoryCatalog" ) ); - dataStores.add( cdl.get( "dataStore" ) ); router = cdl.get( "router" ); planAndImplementationCaching = cdl.getOrDefault( "planAndImplementationCaching", "Both" ); @@ -94,12 +111,23 @@ public MultimediaConfig( Map cdl ) { numberOfThreads = Integer.parseInt( cdl.get( "numberOfThreads" ) ); numberOfWarmUpIterations = Integer.parseInt( cdl.get( "numberOfWarmUpIterations" ) ); + dataStore = cdl.get( "dataStore" ); + multimediaStore = cdl.get( "multimediaStore" ); + dataStores.add( dataStore ); + if ( !multimediaStore.equals( "same" ) ) { + dataStores.add( multimediaStore ); + } numberOfUsers = Integer.parseInt( cdl.get( "numberOfUsers" ) ); albumSize = Integer.parseInt( cdl.get( "albumSize" ) ); postsPerUser = Integer.parseInt( cdl.get( "postsPerUser" ) ); numberOfFriends = Integer.parseInt( cdl.get( "numberOfFriends" ) ); - read = Integer.parseInt( cdl.get( "read" ) ); - write = Integer.parseInt( cdl.get( "write" ) ); + numberOfSelectUserQueries = Integer.parseInt( cdl.get( "numberOfSelectUserQueries" ) ); + numberOfSelectProfilePicQueries = Integer.parseInt( cdl.get( "numberOfSelectProfilePicQueries" ) ); + numberOfSelectProfilePicsQueries = Integer.parseInt( cdl.get( "numberOfSelectProfilePicsQueries" ) ); + numberOfSelectMediaQueries = Integer.parseInt( cdl.get( "numberOfSelectMediaQueries" ) ); + numberOfSelectTimelineQueries = Integer.parseInt( cdl.get( "numberOfSelectTimelineQueries" ) ); + numberOfDeleteTimelineQueries = Integer.parseInt( cdl.get( "numberOfDeleteTimelineQueries" ) ); + numberOfInsertTimelineQueries = Integer.parseInt( cdl.get( "numberOfInsertTimelineQueries" ) ); imgSize = Integer.parseInt( cdl.get( "imgSize" ) ); numberOfFrames = Integer.parseInt( cdl.get( "numberOfFrames" ) ); diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/DeleteRandomTimeline.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/DeleteRandomTimeline.java index 60394277..219df837 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/DeleteRandomTimeline.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/DeleteRandomTimeline.java @@ -31,6 +31,7 @@ import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import kong.unirest.HttpRequest; +import kong.unirest.Unirest; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; @@ -51,8 +52,10 @@ public DeleteRandomTimeline( int numberOfTimelines ) { public Query getNewQuery() { //make sure that only existing posts are deleted int timelineId = ThreadLocalRandom.current().nextInt( 1, numberOfTimelines ); - while ( deletedTimelines.contains( timelineId ) ) { + int counter = 0; + while ( deletedTimelines.contains( timelineId ) && counter < 5 ) { timelineId = ThreadLocalRandom.current().nextInt( 1, numberOfTimelines ); + counter++; } deletedTimelines.add( timelineId ); return new DeleteRandomTimelineQuery( timelineId ); @@ -92,7 +95,8 @@ public Map> getParameterValues() { @Override public HttpRequest getRest() { - return null; + return Unirest.delete( "{protocol}://{host}:{port}/restapi/v1/res/public.timeline" ) + .queryString( "public.timeline.id", "=" + userId ); } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertAlbum.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertAlbum.java index 6b3909e2..d08a57b1 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertAlbum.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertAlbum.java @@ -28,7 +28,9 @@ import com.devskiller.jfairy.Fairy; import com.devskiller.jfairy.producer.person.Person; +import com.google.common.collect.ImmutableList; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -123,13 +125,17 @@ public Map> getParameterValues() { @Override public HttpRequest getRest() { - return null; + return buildRestInsert( "public.album", ImmutableList.of( getRestRowExpression() ) ); } @Override public JsonObject getRestRowExpression() { - return null; + JsonObject row = new JsonObject(); + row.add( "public.album.id", new JsonPrimitive( album_id ) ); + row.add( "public.album.user_id", new JsonPrimitive( user_id ) ); + row.add( "public.album.name", new JsonPrimitive( name ) ); + return row; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertFriends.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertFriends.java index 1d04e3df..ab99c623 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertFriends.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertFriends.java @@ -26,7 +26,9 @@ package org.polypheny.simpleclient.scenario.multimedia.queryBuilder; +import com.google.common.collect.ImmutableList; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import java.util.HashMap; import java.util.Map; import kong.unirest.HttpRequest; @@ -102,13 +104,16 @@ public Map> getParameterValues() { @Override public HttpRequest getRest() { - return null; + return buildRestInsert( "public.followers", ImmutableList.of( getRestRowExpression() ) ); } @Override public JsonObject getRestRowExpression() { - return null; + JsonObject row = new JsonObject(); + row.add( "public.followers.user_id", new JsonPrimitive( user ) ); + row.add( "public.followers.friend_id", new JsonPrimitive( friend ) ); + return row; } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertMedia.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertMedia.java index 953b8e9b..8113e23f 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertMedia.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertMedia.java @@ -27,18 +27,23 @@ import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import java.io.File; import java.sql.Timestamp; +import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import kong.unirest.HttpRequest; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.MultipartInsert; import org.polypheny.simpleclient.query.QueryBuilder; import org.polypheny.simpleclient.scenario.multimedia.MediaGenerator; +@Slf4j public class InsertMedia extends QueryBuilder { private static final AtomicInteger nextId = new AtomicInteger( 1 ); @@ -70,7 +75,7 @@ public BatchableInsert getNewQuery() { } - private static class InsertMediaQuery extends BatchableInsert { + private static class InsertMediaQuery extends MultipartInsert { private static final String SQL = "INSERT INTO \"media\" (\"id\", \"timestamp\", \"album_id\", \"img\", \"video\", \"sound\") VALUES "; private final int id; @@ -89,6 +94,9 @@ public InsertMediaQuery( int id, Timestamp timestamp, int album_id, File img, Fi this.img = img; this.video = video; this.sound = sound; + setFile( "img", img ); + setFile( "video", video ); + setFile( "sound", sound ); } @@ -104,9 +112,9 @@ public String getSqlRowExpression() { + id + "," + "timestamp '" + timestamp.toString() + "'," + album_id + "," - + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( img ) ) + "," - + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( video ) ) + "," - + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( sound ) ) + + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( img, 2 ) ) + "," + + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( video, 2 ) ) + "," + + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( sound, 2 ) ) + ")"; } @@ -123,9 +131,9 @@ public Map> getParameterValues() { map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, id ) ); map.put( 2, new ImmutablePair<>( DataTypes.TIMESTAMP, timestamp ) ); map.put( 3, new ImmutablePair<>( DataTypes.INTEGER, album_id ) ); - map.put( 4, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( img ) ) ); - map.put( 5, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( video ) ) ); - map.put( 6, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( sound ) ) ); + map.put( 4, new ImmutablePair<>( DataTypes.FILE, img ) ); + map.put( 5, new ImmutablePair<>( DataTypes.FILE, video ) ); + map.put( 6, new ImmutablePair<>( DataTypes.FILE, sound ) ); return map; } @@ -138,7 +146,15 @@ public HttpRequest getRest() { @Override public JsonObject getRestRowExpression() { - return null; + JsonObject set = new JsonObject(); + String table = getTable() + "."; + set.add( table + "id", new JsonPrimitive( id ) ); + set.add( table + "timestamp", new JsonPrimitive( timestamp.toLocalDateTime().format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) ) ); + set.add( table + "album_id", new JsonPrimitive( album_id ) ); + set.add( table + "img", new JsonPrimitive( "img" ) ); + set.add( table + "video", new JsonPrimitive( "video" ) ); + set.add( table + "sound", new JsonPrimitive( "sound" ) ); + return set; } @@ -147,6 +163,11 @@ public String getTable() { return "public.media"; } + + @Override + public Map getRestParameters() { + return null; + } } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertRandomTimeline.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertRandomTimeline.java index d824dbb6..161df7b9 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertRandomTimeline.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertRandomTimeline.java @@ -28,8 +28,10 @@ import com.devskiller.jfairy.Fairy; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import java.io.File; import java.sql.Timestamp; +import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; @@ -38,6 +40,7 @@ import lombok.Getter; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.MultipartInsert; import org.polypheny.simpleclient.query.QueryBuilder; import org.polypheny.simpleclient.scenario.multimedia.MediaGenerator; @@ -48,24 +51,34 @@ public class InsertRandomTimeline extends QueryBuilder { private static final AtomicInteger nextId = new AtomicInteger( 1 ); private final int numberOfUsers; + private final int postsPerUser; private final int imgSize; private final int numberOfFrames; private final int fileSizeKB; + private final boolean isWarmup; - public InsertRandomTimeline( int numberOfUsers, int imgSize, int numberOfFrames, int fileSizeKB ) { + public InsertRandomTimeline( int numberOfUsers, int postsPerUser, int imgSize, int numberOfFrames, int fileSizeKB, boolean isWarmup ) { this.numberOfUsers = numberOfUsers; + this.postsPerUser = postsPerUser; this.imgSize = imgSize; this.numberOfFrames = numberOfFrames; this.fileSizeKB = fileSizeKB; + this.isWarmup = isWarmup; } @Override public BatchableInsert getNewQuery() { Fairy fairy = Fairy.create(); + int id = nextId.getAndIncrement(); + if ( isWarmup ) { + id = id * -1; + } else { + id = id + numberOfUsers * postsPerUser + 1; + } return new InsertRandomTimelineQuery( - nextId.getAndIncrement(), + id, MediaGenerator.randomTimestamp(), ThreadLocalRandom.current().nextInt( 1, numberOfUsers ), fairy.textProducer().paragraph( 5 ), @@ -76,7 +89,7 @@ public BatchableInsert getNewQuery() { } - private static class InsertRandomTimelineQuery extends BatchableInsert { + private static class InsertRandomTimelineQuery extends MultipartInsert { private static final String SQL = "INSERT INTO \"timeline\" (\"id\", \"timestamp\", \"user_id\", \"message\", \"img\", \"video\", \"sound\") VALUES "; private final int timelineId; @@ -97,6 +110,9 @@ public InsertRandomTimelineQuery( int timelineId, Timestamp timestamp, int userI this.img = img; this.video = video; this.sound = sound; + setFile( "img", img ); + setFile( "video", video ); + setFile( "sound", sound ); } @@ -113,9 +129,9 @@ public String getSqlRowExpression() { + "timestamp '" + timestamp.toString() + "'," + userId + "," + "'" + message + "'," - + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( img, 2 ) ) + "," - + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( video, 2 ) ) + "," - + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( sound, 2 ) ) + + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( img, 1 ) ) + "," + + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( video, 1 ) ) + "," + + MediaGenerator.insertByteHexString( MediaGenerator.getAndDeleteFile( sound, 1 ) ) + ")"; } @@ -133,9 +149,9 @@ public Map> getParameterValues() { map.put( 2, new ImmutablePair<>( DataTypes.TIMESTAMP, timestamp ) ); map.put( 3, new ImmutablePair<>( DataTypes.INTEGER, userId ) ); map.put( 4, new ImmutablePair<>( DataTypes.VARCHAR, message ) ); - map.put( 5, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( img, 2 ) ) ); - map.put( 6, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( video, 2 ) ) ); - map.put( 7, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( sound, 2 ) ) ); + map.put( 5, new ImmutablePair<>( DataTypes.FILE, img ) ); + map.put( 6, new ImmutablePair<>( DataTypes.FILE, video ) ); + map.put( 7, new ImmutablePair<>( DataTypes.FILE, sound ) ); return map; } @@ -148,7 +164,16 @@ public HttpRequest getRest() { @Override public JsonObject getRestRowExpression() { - return null; + JsonObject set = new JsonObject(); + String table = getTable() + "."; + set.add( table + "id", new JsonPrimitive( timelineId ) ); + set.add( table + "timestamp", new JsonPrimitive( timestamp.toLocalDateTime().format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) ) ); + set.add( table + "user_id", new JsonPrimitive( userId ) ); + set.add( table + "message", new JsonPrimitive( message ) ); + set.add( table + "img", new JsonPrimitive( "img" ) ); + set.add( table + "video", new JsonPrimitive( "video" ) ); + set.add( table + "sound", new JsonPrimitive( "sound" ) ); + return set; } @@ -157,6 +182,10 @@ public String getTable() { return "public.timeline"; } + @Override + public Map getRestParameters() { + return null; + } } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertTimeline.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertTimeline.java index 0c4e89db..f60b215a 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertTimeline.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertTimeline.java @@ -28,14 +28,17 @@ import com.devskiller.jfairy.Fairy; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import java.io.File; import java.sql.Timestamp; +import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import kong.unirest.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.MultipartInsert; import org.polypheny.simpleclient.query.QueryBuilder; import org.polypheny.simpleclient.scenario.multimedia.MediaGenerator; @@ -73,7 +76,7 @@ public BatchableInsert getNewQuery() { } - private static class InsertTimelineQuery extends BatchableInsert { + private static class InsertTimelineQuery extends MultipartInsert { private static final String SQL = "INSERT INTO \"timeline\" (\"id\", \"timestamp\", \"user_id\", \"message\", \"img\", \"video\", \"sound\") VALUES "; private final int timelineId; @@ -94,6 +97,9 @@ public InsertTimelineQuery( int timelineId, Timestamp timestamp, int userId, Str this.img = img; this.video = video; this.sound = sound; + setFile( "img", img ); + setFile( "video", video ); + setFile( "sound", sound ); } @@ -130,9 +136,9 @@ public Map> getParameterValues() { map.put( 2, new ImmutablePair<>( DataTypes.TIMESTAMP, timestamp ) ); map.put( 3, new ImmutablePair<>( DataTypes.INTEGER, userId ) ); map.put( 4, new ImmutablePair<>( DataTypes.VARCHAR, message ) ); - map.put( 5, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( img ) ) ); - map.put( 6, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( video ) ) ); - map.put( 7, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( sound ) ) ); + map.put( 5, new ImmutablePair<>( DataTypes.FILE, img ) ); + map.put( 6, new ImmutablePair<>( DataTypes.FILE, video ) ); + map.put( 7, new ImmutablePair<>( DataTypes.FILE, sound ) ); return map; } @@ -145,7 +151,17 @@ public HttpRequest getRest() { @Override public JsonObject getRestRowExpression() { - return null; + JsonObject set = new JsonObject(); + String table = getTable() + "."; + set.add( table + "id", new JsonPrimitive( timelineId ) ); + set.add( table + "timestamp", new JsonPrimitive( timestamp.toLocalDateTime().format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) ) ); + set.add( table + "user_id", new JsonPrimitive( userId ) ); + set.add( table + "message", new JsonPrimitive( message ) ); + set.add( table + "img", new JsonPrimitive( "img" ) ); + set.add( table + "video", new JsonPrimitive( "video" ) ); + set.add( table + "sound", new JsonPrimitive( "sound" ) ); + return set; + } @@ -154,6 +170,10 @@ public String getTable() { return "public.timeline"; } + @Override + public Map getRestParameters() { + return null; + } } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertUser.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertUser.java index a916a246..85cd5c9c 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertUser.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/InsertUser.java @@ -29,6 +29,7 @@ import com.devskiller.jfairy.Fairy; import com.devskiller.jfairy.producer.person.Person; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import java.io.File; import java.util.HashMap; import java.util.Locale; @@ -37,7 +38,7 @@ import java.util.concurrent.atomic.AtomicInteger; import kong.unirest.HttpRequest; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.polypheny.simpleclient.query.BatchableInsert; +import org.polypheny.simpleclient.query.MultipartInsert; import org.polypheny.simpleclient.query.QueryBuilder; import org.polypheny.simpleclient.scenario.multimedia.MediaGenerator; @@ -78,7 +79,7 @@ public InsertUserQuery getNewQuery() { } - public static class InsertUserQuery extends BatchableInsert { + public static class InsertUserQuery extends MultipartInsert { private static final String SQL = "INSERT INTO \"users\" (\"id\", \"firstName\", \"lastName\", \"email\", \"password\", \"profile_pic\") VALUES "; public final int id; @@ -97,6 +98,7 @@ public InsertUserQuery( int id, String firstName, String lastName, String email, this.email = email; this.password = password; this.profile_pic = profile_pic; + setFile( "profile_pic", profile_pic ); } @@ -133,7 +135,7 @@ public Map> getParameterValues() { map.put( 3, new ImmutablePair<>( DataTypes.VARCHAR, lastName ) ); map.put( 4, new ImmutablePair<>( DataTypes.VARCHAR, email ) ); map.put( 5, new ImmutablePair<>( DataTypes.VARCHAR, password ) ); - map.put( 6, new ImmutablePair<>( DataTypes.BYTE_ARRAY, MediaGenerator.getAndDeleteFile( profile_pic ) ) ); + map.put( 6, new ImmutablePair<>( DataTypes.FILE, profile_pic ) ); return map; } @@ -146,15 +148,28 @@ public HttpRequest getRest() { @Override public JsonObject getRestRowExpression() { - return null; + JsonObject set = new JsonObject(); + String table = getTable() + "."; + set.add( table + "id", new JsonPrimitive( id ) ); + set.add( table + "firstname", new JsonPrimitive( firstName ) ); + set.add( table + "lastname", new JsonPrimitive( lastName ) ); + set.add( table + "email", new JsonPrimitive( email ) ); + set.add( table + "password", new JsonPrimitive( password ) ); + set.add( table + "profile_pic", new JsonPrimitive( "profile_pic" ) ); + return set; + } @Override public String getTable() { - return "public.user"; + return "public.users"; } + @Override + public Map getRestParameters() { + return null; + } } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectMediaWhereAlbum.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectMediaWhereAlbum.java new file mode 100644 index 00000000..9b7d37b2 --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectMediaWhereAlbum.java @@ -0,0 +1,107 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Databases and Information Systems Research Group, University of Basel, Switzerland + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.multimedia.queryBuilder; + + +import java.util.HashMap; +import java.util.Map; +import java.util.StringJoiner; +import java.util.concurrent.ThreadLocalRandom; +import kong.unirest.HttpRequest; +import kong.unirest.Unirest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; + + +public class SelectMediaWhereAlbum extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + private static final int LIMIT = 4; + + private final int numberOfAlbums; + + + public SelectMediaWhereAlbum( int numberOfAlbums ) { + this.numberOfAlbums = numberOfAlbums; + } + + + @Override + public Query getNewQuery() { + int albumId = ThreadLocalRandom.current().nextInt( 1, numberOfAlbums + 1 ); + return new SelectMediaWhereAlbumQuery( albumId ); + } + + + public static class SelectMediaWhereAlbumQuery extends Query { + + private final int albumId; + + + public SelectMediaWhereAlbumQuery( int albumId ) { + super( EXPECT_RESULT ); + this.albumId = albumId; + } + + + @Override + public String getSql() { + return "SELECT \"timestamp\", \"img\", \"video\", \"sound\" FROM \"public\".\"media\" WHERE \"album_id\" = " + albumId + " LIMIT " + LIMIT; + } + + + @Override + public String getParameterizedSqlQuery() { + return "SELECT \"timestamp\", \"img\", \"video\", \"sound\" FROM \"public\".\"media\" WHERE \"album_id\" = ? LIMIT " + LIMIT; + } + + + @Override + public Map> getParameterValues() { + Map> map = new HashMap<>(); + map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, albumId ) ); + return map; + } + + + @Override + public HttpRequest getRest() { + String table = "public.media."; + StringJoiner joiner = new StringJoiner( "," ); + joiner.add( table + "timestamp" ); + joiner.add( table + "img" ); + joiner.add( table + "video" ); + joiner.add( table + "sound" ); + return Unirest.get( "{protocol}://{host}:{port}/restapi/v1/res/public.media" ) + .queryString( "public.media.album_id", "=" + albumId ) + .queryString( "_project", joiner.toString() ) + .queryString( "_limit", LIMIT ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectMultipleProfilePics.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectMultipleProfilePics.java new file mode 100644 index 00000000..9f19138d --- /dev/null +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectMultipleProfilePics.java @@ -0,0 +1,109 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Databases and Information Systems Research Group, University of Basel, Switzerland + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package org.polypheny.simpleclient.scenario.multimedia.queryBuilder; + + +import java.util.Map; +import java.util.StringJoiner; +import java.util.concurrent.ThreadLocalRandom; +import kong.unirest.HttpRequest; +import kong.unirest.Unirest; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.polypheny.simpleclient.query.Query; +import org.polypheny.simpleclient.query.QueryBuilder; + + +public class SelectMultipleProfilePics extends QueryBuilder { + + private static final boolean EXPECT_RESULT = true; + private static final int LIMIT = 100; + + private final int numberOfUsers; + + + public SelectMultipleProfilePics( int numberOfUsers ) { + this.numberOfUsers = numberOfUsers; + } + + + @Override + public Query getNewQuery() { + int offset; + if ( numberOfUsers > LIMIT ) { + offset = ThreadLocalRandom.current().nextInt( 1, numberOfUsers + 1 - LIMIT ); + } else { + offset = 0; + } + return new SelectMultipleProfilePicsQuery( numberOfUsers, offset ); + } + + + public static class SelectMultipleProfilePicsQuery extends Query { + + private final int numberOfUsers; + private final int offset; + + + public SelectMultipleProfilePicsQuery( int numberOfUsers, int offset ) { + super( EXPECT_RESULT ); + this.numberOfUsers = numberOfUsers; + this.offset = offset; + } + + + @Override + public String getSql() { + return "SELECT firstName, profile_pic FROM \"users\" LIMIT " + LIMIT + " OFFSET " + offset; + } + + + @Override + public String getParameterizedSqlQuery() { + return null; + } + + + @Override + public Map> getParameterValues() { + return null; + } + + + @Override + public HttpRequest getRest() { + String table = "public.users."; + StringJoiner joiner = new StringJoiner( "," ); + joiner.add( table + "firstname" ); + joiner.add( table + "profile_pic" ); + return Unirest.get( "{protocol}://{host}:{port}/restapi/v1/res/public.users" ) + .queryString( "_project", joiner.toString() ) + .queryString( "_limit", LIMIT ) + .queryString( "_offset", offset ); + } + + } + +} diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomAlbum.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomProfilePic.java similarity index 71% rename from src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomAlbum.java rename to src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomProfilePic.java index 7bc73bfe..192b8674 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomAlbum.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomProfilePic.java @@ -30,19 +30,20 @@ import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import kong.unirest.HttpRequest; +import kong.unirest.Unirest; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; -public class SelectRandomAlbum extends QueryBuilder { +public class SelectRandomProfilePic extends QueryBuilder { private static final boolean EXPECT_RESULT = true; private final int numberOfUsers; - public SelectRandomAlbum( int numberOfUsers ) { + public SelectRandomProfilePic( int numberOfUsers ) { this.numberOfUsers = numberOfUsers; } @@ -50,16 +51,16 @@ public SelectRandomAlbum( int numberOfUsers ) { @Override public Query getNewQuery() { int userId = ThreadLocalRandom.current().nextInt( 1, numberOfUsers + 1 ); - return new SelectRandomAlbumQuery( userId ); + return new SelectRandomProfilePicQuery( userId ); } - public static class SelectRandomAlbumQuery extends Query { + public static class SelectRandomProfilePicQuery extends Query { private final int userId; - public SelectRandomAlbumQuery( int userId ) { + public SelectRandomProfilePicQuery( int userId ) { super( EXPECT_RESULT ); this.userId = userId; } @@ -67,21 +68,13 @@ public SelectRandomAlbumQuery( int userId ) { @Override public String getSql() { - return "SELECT album.name AS album_name, media.\"timestamp\", media.img, media.\"video\", media.\"sound\" " - + "FROM public.media, public.album, public.\"users\" WHERE " - + "media.album_id = album.id " - + "AND album.user_id = \"users\".id " - + "AND \"users\".id=" + userId; + return "SELECT profile_pic FROM \"users\" WHERE id=" + userId; } @Override public String getParameterizedSqlQuery() { - return "SELECT album.name AS album_name, media.\"timestamp\", media.img, media.\"video\", media.\"sound\" " - + "FROM public.media, public.album, public.\"users\" WHERE " - + "media.album_id = album.id " - + "AND album.user_id = \"users\".id " - + "AND \"users\".id=?"; + return "SELECT profile_pic FROM \"users\" WHERE id=?"; } @@ -95,7 +88,9 @@ public Map> getParameterValues() { @Override public HttpRequest getRest() { - return null; + return Unirest.get( "{protocol}://{host}:{port}/restapi/v1/res/public.users" ) + .queryString( "public.users.id", "=" + userId ) + .queryString( "_project", "public.users.profile_pic" ); } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomTimeline.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomTimeline.java index 5082262c..fe96196a 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomTimeline.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomTimeline.java @@ -28,8 +28,10 @@ import java.util.HashMap; import java.util.Map; +import java.util.StringJoiner; import java.util.concurrent.ThreadLocalRandom; import kong.unirest.HttpRequest; +import kong.unirest.Unirest; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; @@ -39,72 +41,63 @@ public class SelectRandomTimeline extends QueryBuilder { private static final boolean EXPECT_RESULT = true; - private final int numberOfUsers; + private final int numberOfTimelineEntries; - public SelectRandomTimeline( int numberOfUsers ) { - this.numberOfUsers = numberOfUsers; + public SelectRandomTimeline( int numberOfTimelineEntries ) { + this.numberOfTimelineEntries = numberOfTimelineEntries; } @Override public Query getNewQuery() { - int userId = ThreadLocalRandom.current().nextInt( 1, numberOfUsers + 1 ); - return new SelectRandomTimelineQuery( userId ); + int id = ThreadLocalRandom.current().nextInt( 1, numberOfTimelineEntries + 1 ); + return new SelectTimelineWhereUserQuery( id ); } - public static class SelectRandomTimelineQuery extends Query { + public static class SelectTimelineWhereUserQuery extends Query { - private final int userId; + private final int id; - public SelectRandomTimelineQuery( int userId ) { + public SelectTimelineWhereUserQuery( int id ) { super( EXPECT_RESULT ); - this.userId = userId; + this.id = id; } @Override public String getSql() { - //TODO LIMIT - return "SELECT friend.firstname, friend.profile_pic, timeline.message, timeline.img, timeline.\"video\", timeline.\"sound\" " - + "FROM public.timeline, " - + "public.\"users\" usr, " - + "public.\"users\" friend, " - + "public.followers " - + "WHERE usr.id = followers.\"user_id\" " - + "AND friend.id = followers.friend_id " - + "AND timeline.user_id = friend.id " - + "AND usr.id=" + userId; + return "SELECT \"message\", \"img\", \"video\", \"sound\" FROM \"timeline\" WHERE \"id\" = " + id; } @Override public String getParameterizedSqlQuery() { - return "SELECT friend.firstname, friend.profile_pic, timeline.message, timeline.img, timeline.\"video\", timeline.\"sound\" " - + "FROM public.timeline, " - + "public.\"users\" usr, " - + "public.\"users\" friend, " - + "public.followers " - + "WHERE usr.id = followers.\"user_id\" " - + "AND friend.id = followers.friend_id " - + "AND timeline.user_id = friend.id " - + "AND usr.id=?"; + return "SELECT \"message\", \"img\", \"video\", \"sound\" FROM \"timeline\" WHERE \"id\" = ?"; } @Override public Map> getParameterValues() { Map> map = new HashMap<>(); - map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, userId ) ); + map.put( 1, new ImmutablePair<>( DataTypes.INTEGER, id ) ); return map; } @Override public HttpRequest getRest() { - return null; + String table = "public.timeline."; + StringJoiner joiner = new StringJoiner( "," ); + joiner.add( table + "message" ); + joiner.add( table + "img" ); + joiner.add( table + "video" ); + joiner.add( table + "sound" ); + return Unirest.get( "{protocol}://{host}:{port}/restapi/v1/res/public.timeline" ) + .queryString( "public.timeline.id", "=" + id ) + .queryString( "_project", joiner.toString() ); } } diff --git a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomUser.java b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomUser.java index eeb5a43b..ab22c789 100644 --- a/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomUser.java +++ b/src/main/java/org/polypheny/simpleclient/scenario/multimedia/queryBuilder/SelectRandomUser.java @@ -30,6 +30,7 @@ import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import kong.unirest.HttpRequest; +import kong.unirest.Unirest; import org.apache.commons.lang3.tuple.ImmutablePair; import org.polypheny.simpleclient.query.Query; import org.polypheny.simpleclient.query.QueryBuilder; @@ -87,7 +88,8 @@ public Map> getParameterValues() { @Override public HttpRequest getRest() { - return null; + return Unirest.get( "{protocol}://{host}:{port}/restapi/v1/res/public.users" ) + .queryString( "public.users.id", "=" + userId ); } } diff --git a/src/main/resources/org/polypheny/simpleclient/scenario/multimedia/multimedia.properties b/src/main/resources/org/polypheny/simpleclient/scenario/multimedia/multimedia.properties index 692b33c0..9ee39f77 100644 --- a/src/main/resources/org/polypheny/simpleclient/scenario/multimedia/multimedia.properties +++ b/src/main/resources/org/polypheny/simpleclient/scenario/multimedia/multimedia.properties @@ -5,19 +5,26 @@ progressReportBase = 100 numberOfWarmUpIterations = 4 # Data Generation +dataStore = hsqldb +multimediaStore = file numberOfUsers = 10 -postsPerUser = 5 -numberOfFriends = 5 +postsPerUser = 2 +numberOfFriends = 1 #media items per album: -albumSize = 5 +albumSize = 2 #img imgSize = 100 #video numberOfFrames = 20 #sound -fileSizeKB = 10 +fileSizeKB = 45000 #Workload -maxBatchSize = 10 -read = 100 -write = 10 \ No newline at end of file +maxBatchSize = 2 +numberOfSelectUserQueries = 10 +numberOfSelectProfilePicQueries = 10 +numberOfSelectProfilePicsQueries = 10 +numberOfSelectMediaQueries = 10 +numberOfSelectTimelineQueries = 10 +numberOfDeleteTimelineQueries = 10 +numberOfInsertTimelineQueries = 10 \ No newline at end of file