1919import java .sql .Connection ;
2020import javax .sql .rowset .CachedRowSet ;
2121import java .text .DecimalFormat ;
22+ import java .util .List ;
2223
2324import static com .crunchydata .controller .TableController .getTableMap ;
25+ import static com .crunchydata .services .Reporter .createSection ;
26+ import static com .crunchydata .services .Reporter .generateHtmlReport ;
2427import static com .crunchydata .util .Settings .*;
2528
2629import com .crunchydata .controller .ColumnController ;
@@ -44,8 +47,9 @@ public class pgCompare {
4447 private static final String THREAD_NAME = "main" ;
4548
4649 private static String action = "reconcile" ;
50+ private static String reportFileName ;
4751 private static Integer batchParameter ;
48- private static boolean check ;
52+ private static boolean check , genReport ;
4953 private static CommandLine cmd ;
5054 private static Integer pid = 1 ;
5155 private static Connection connRepo ;
@@ -268,6 +272,7 @@ private static CommandLine parseCommandLine(String[] args) {
268272 options .addOption (Option .builder ("h" ).longOpt ("help" ).argName ("help" ).hasArg (false ).desc ("Usage and help" ).build ());
269273 options .addOption (Option .builder ("i" ).longOpt ("init" ).argName ("init" ).hasArg (false ).desc ("Initialize repository" ).build ());
270274 options .addOption (Option .builder ("p" ).longOpt ("project" ).argName ("project" ).hasArg (true ).desc ("Project ID" ).build ());
275+ options .addOption (Option .builder ("r" ).longOpt ("report" ).argName ("report" ).hasArg (true ).desc ("Generate report" ).build ());
271276 options .addOption (Option .builder ("t" ).longOpt ("table" ).argName ("table" ).hasArg (true ).desc ("Limit to specified table" ).build ());
272277 options .addOption (Option .builder ("v" ).longOpt ("version" ).argName ("version" ).hasArg (false ).desc ("Version" ).build ());
273278
@@ -291,6 +296,8 @@ private static CommandLine parseCommandLine(String[] args) {
291296 // Capture Argument Values
292297 batchParameter = (cmd .hasOption ("batch" )) ? Integer .parseInt (cmd .getOptionValue ("batch" )) : (System .getenv ("PGCOMPARE-BATCH" ) == null ) ? 0 : Integer .parseInt (System .getenv ("PGCOMPARE-BATCH" ));
293298 check = cmd .hasOption ("check" );
299+ genReport = cmd .hasOption ("report" );
300+ reportFileName = (cmd .hasOption ("report" )) ? cmd .getOptionValue ("report" ) : "" ;
294301
295302 // Determine the desired action, reconcile, discovery or init.
296303 // reconcile = Perform comparison between source and target databases.
@@ -307,6 +314,17 @@ private static CommandLine parseCommandLine(String[] args) {
307314 }
308315 }
309316
317+ //
318+ // Create Column Metadata JSON Object
319+ //
320+ private static JSONObject createReportColumn (String header , String key , String align , boolean commaFormat ) {
321+ return new JSONObject ()
322+ .put ("columnHeader" , header )
323+ .put ("columnClass" , align )
324+ .put ("columnKey" , key )
325+ .put ("commaFormat" , commaFormat );
326+ }
327+
310328 //
311329 // Create Summary
312330 //
@@ -351,6 +369,58 @@ private static void createSummary(int tablesProcessed, JSONArray runResult, long
351369 printSummary (String .format ("Total Out-of-Sync = %s" , df .format (outOfSyncRows )), 2 );
352370 printSummary (String .format ("Through-put (rows/per second) = %s" , df .format (totalRows / elapsedTime )), 2 );
353371
372+ // Generate Report
373+ if (genReport ) {
374+ // Create JSON report
375+ JSONObject jobSummary = new JSONObject ()
376+ .put ("tablesProcessed" , df .format (tablesProcessed ))
377+ .put ("elapsedTime" , df .format (elapsedTime ))
378+ .put ("totalRows" , df .format (totalRows ))
379+ .put ("outOfSyncRows" , df .format (outOfSyncRows ))
380+ .put ("rowsPerSecond" , df .format (totalRows / elapsedTime ));
381+
382+
383+ JSONArray jobSummaryLayout = new JSONArray (List .of (
384+ createReportColumn ("Tables Processed" , "tablesProcessed" , "right-align" , false ),
385+ createReportColumn ("Elapsed Time" , "elapsedTime" , "right-align" , false ),
386+ createReportColumn ("Rows per Second" , "rowsPerSecond" , "right-align" , false ),
387+ createReportColumn ("Total Rows" , "totalRows" , "right-align" , false ),
388+ createReportColumn ("Out of Sync Rows" , "outOfSyncRows" , "right-align" , false )
389+ ));
390+
391+
392+ JSONArray runResultLayout = new JSONArray (List .of (
393+ createReportColumn ("Table" , "tableName" , "left-align" , false ),
394+ createReportColumn ("Compare Status" , "compareStatus" , "left-align" , false ),
395+ createReportColumn ("Elapsed Time" , "elapsedTime" , "right-align" , true ),
396+ createReportColumn ("Rows per Second" , "rowsPerSecond" , "right-align" , true ),
397+ createReportColumn ("Rows Total" , "totalRows" , "right-align" , true ),
398+ createReportColumn ("Rows Equal" , "equal" , "right-align" , true ),
399+ createReportColumn ("Rows Not Equal" , "notEqual" , "right-align" , true ),
400+ createReportColumn ("Rows Missing on Source" , "missingSource" , "right-align" , true ),
401+ createReportColumn ("Rows Missing on Target" , "missingTarget" , "right-align" , true )
402+ ));
403+
404+ JSONArray reportArray = new JSONArray ()
405+ .put (createSection ("Job Summary" , new JSONArray ().put (jobSummary ), jobSummaryLayout )) // Pass JSONObject directly
406+ .put (createSection ("Table Summary" , runResult , runResultLayout )); // Pass runResult
407+
408+ if (check ) {
409+ JSONArray runCheckResultLayout = new JSONArray (List .of (
410+ createReportColumn ("Primary Key" , "pk" , "left-align" , false ),
411+ createReportColumn ("Status" , "compareStatus" , "left-align" , false ),
412+ createReportColumn ("Result" , "compareResult" , "left-align" , false )
413+ ));
414+
415+ for (int i =0 ; i <runResult .length (); i ++ ) {
416+ reportArray .put (createSection (String .format ("Table: %s" , runResult .getJSONObject (i ).getString ("tableName" )), runResult .getJSONObject (i ).getJSONObject ("checkResult" ).getJSONArray ("data" ), runCheckResultLayout ));
417+ }
418+ }
419+
420+ generateHtmlReport (reportArray , reportFileName ,"pgCompare Summary" );
421+
422+ }
423+
354424 } else {
355425 // Print message if no tables processed or out of sync records found
356426 String msg = (check ) ? "No out of sync records found" : "No tables were processed. Need to do discovery? Used correct batch nbr?" ;
@@ -375,7 +445,9 @@ public static void showHelp () {
375445 System .out .println (" -b|--batch <batch nbr>" );
376446 System .out .println (" -c|--check Check out of sync rows" );
377447 System .out .println (" -d|--discovery <schema> Discover tables in database" );
448+ System .out .println (" -i|--init <schema> Init tables in database" );
378449 System .out .println (" -p|--project Project ID" );
450+ System .out .println (" -r|--report <file> Create html report of compare" );
379451 System .out .println (" -t|--table <target table>" );
380452 System .out .println (" --help" );
381453 System .out .println ();
0 commit comments