1515import java .text .SimpleDateFormat ;
1616import java .util .ArrayList ;
1717import java .util .Date ;
18+ import java .util .HashMap ;
1819import java .util .List ;
20+ import java .util .Map ;
1921import java .util .concurrent .ExecutorService ;
2022import java .util .concurrent .Executors ;
2123import java .util .concurrent .ScheduledExecutorService ;
2224import java .util .concurrent .TimeUnit ;
2325import java .util .concurrent .atomic .AtomicLong ;
2426
2527import com .beust .jcommander .JCommander ;
28+ import com .beust .jcommander .JCommander .Builder ;
2629
2730import sqlancer .cockroachdb .CockroachDBProvider ;
2831import sqlancer .mariadb .MariaDBProvider ;
@@ -56,7 +59,7 @@ public final static class StateLogger {
5659 public FileWriter currentFileWriter ;
5760 private static final List <String > initializedProvidersNames = new ArrayList <>();
5861 private boolean logEachSelect = true ;
59- private DatabaseProvider provider ;
62+ private DatabaseProvider <?, ?> provider ;
6063
6164 private final static class AlsoWriteToConsoleFileWriter extends FileWriter {
6265
@@ -77,7 +80,7 @@ public void write(String str) throws IOException {
7780 }
7881 }
7982
80- public StateLogger (String databaseName , DatabaseProvider provider , MainOptions options ) {
83+ public StateLogger (String databaseName , DatabaseProvider <?, ?> provider , MainOptions options ) {
8184 this .provider = provider ;
8285 File dir = new File (LOG_DIRECTORY , provider .getLogFileSubdirectoryName ());
8386 if (dir .exists () && !dir .isDirectory ()) {
@@ -92,7 +95,7 @@ public StateLogger(String databaseName, DatabaseProvider provider, MainOptions o
9295 }
9396 }
9497
95- private synchronized void ensureExistsAndIsEmpty (File dir , DatabaseProvider provider ) {
98+ private synchronized void ensureExistsAndIsEmpty (File dir , DatabaseProvider <?, ?> provider ) {
9699 if (initializedProvidersNames .contains (provider .getLogFileSubdirectoryName ())) {
97100 return ;
98101 }
@@ -289,9 +292,35 @@ public static void printArray(Object[] arr) {
289292 }
290293
291294 public static void main (String [] args ) {
292-
295+ List <DatabaseProvider <?, ?>> providers = new ArrayList <>();
296+ providers .add (new SQLite3Provider ());
297+ providers .add (new CockroachDBProvider ());
298+ providers .add (new MySQLProvider ());
299+ providers .add (new MariaDBProvider ());
300+ providers .add (new TiDBProvider ());
301+ providers .add (new PostgresProvider ());
302+ providers .add (new TDEngineProvider ());
303+ Map <String , DatabaseProvider <?, ?>> nameToProvider = new HashMap <>();
304+ Map <String , Object > nameToOptions = new HashMap <>();
293305 MainOptions options = new MainOptions ();
294- JCommander .newBuilder ().addObject (options ).build ().parse (args );
306+ Builder commandBuilder = JCommander .newBuilder ()
307+ .addObject (options );
308+ for (DatabaseProvider <?, ?> provider : providers ) {
309+ String name = provider .getLogFileSubdirectoryName ();
310+ Object command = provider .getCommand ();
311+ if (command == null ) {
312+ throw new IllegalStateException ();
313+ }
314+ nameToProvider .put (name , provider );
315+ nameToOptions .put (name , command );
316+ commandBuilder = commandBuilder .addCommand (name , command );
317+ }
318+ JCommander jc = commandBuilder .build ();
319+ jc .parse (args );
320+ if (jc .getParsedCommand () == null ) {
321+ jc .usage ();
322+ System .exit (-1 );
323+ }
295324
296325 final ScheduledExecutorService scheduler = Executors .newScheduledThreadPool (1 );
297326 scheduler .scheduleAtFixedRate (new Runnable () {
@@ -336,59 +365,42 @@ public void run() {
336365
337366 StateToReproduce stateToRepro ;
338367 StateLogger logger ;
339- DatabaseProvider <?> provider ;
368+ DatabaseProvider <?, ? > provider ;
340369
341370 @ Override
342371 public void run () {
343- switch (options .getDbms ()) {
344- case MariaDB :
345- provider = new MariaDBProvider ();
346- break ;
347- case MySQL :
348- provider = new MySQLProvider ();
349- break ;
350- case PostgreSQL :
351- provider = new PostgresProvider ();
352- break ;
353- case SQLite3 :
354- provider = new SQLite3Provider ();
355- break ;
356- case TDEngine :
357- provider = new TDEngineProvider ();
358- break ;
359- case CockroachDB :
360- provider = new CockroachDBProvider ();
361- break ;
362- case TiDB :
363- provider = new TiDBProvider ();
364- break ;
365- }
366372 runThread (databaseName );
367373 }
368374
369375 private void runThread (final String databaseName ) {
370376 Thread .currentThread ().setName (databaseName );
371377 while (true ) {
378+ // create a new instance of the provider in case it has a global state
379+ try {
380+ provider = nameToProvider .get (jc .getParsedCommand ()).getClass ().newInstance ();
381+ } catch (Exception e ) {
382+ throw new AssertionError (e );
383+ }
372384 stateToRepro = provider .getStateToReproduce (databaseName );
373385 logger = new StateLogger (databaseName , provider , options );
374386 try (Connection con = provider .createDatabase (databaseName , stateToRepro )) {
375387 QueryManager manager = new QueryManager (con , stateToRepro );
376388 java .sql .DatabaseMetaData meta = con .getMetaData ();
377389 stateToRepro .databaseVersion = meta .getDatabaseProductVersion ();
378- GlobalState state = (GlobalState ) provider .generateGlobalState ();
390+ GlobalState <?> state = (GlobalState <?> ) provider .generateGlobalState ();
379391 state .setState (stateToRepro );
380392 Randomly r = new Randomly ();
381393 state .setDatabaseName (databaseName );
382394 state .setConnection (con );
383395 state .setRandomly (r );
384396 state .setMainOptions (options );
397+ Object dmbsSpecificOptions = nameToOptions .get (jc .getParsedCommand ());
398+ state .setDmbsSpecificOptions (dmbsSpecificOptions );
385399 state .setStateLogger (logger );
386400 state .setManager (manager );
387401 Method method = provider .getClass ().getMethod ("generateAndTestDatabase" , state .getClass ());
388402 method .setAccessible (true );
389403 method .invoke (provider , state );
390- // provider.generateAndTestDatabase(state);
391- // provider.generateAndTestDatabase(databaseName, con, logger, state, manager, options);
392404 } catch (IgnoreMeException e ) {
393405 continue ;
394406 } catch (InvocationTargetException e ) {
0 commit comments