src.php

<?php


/**
 * Export .ods files to csv files using `libreoffice` command
 *
 */
function export_to_csv($odsDir, $csvDir){
    // this old command produced not utf8 output so was an issue
    // $cmd = "libreoffice --headless --convert-to csv \"$odsDir\"/* --outdir \"$csvDir\"";
    

    // the --infilter suggestion comes from https://unix.stackexchange.com/questions/259361/specify-encoding-with-libreoffice-convert-to-csv
    $cmd = "libreoffice --headless --convert-to csv --infilter=CSV:44,34,76,1 \"$odsDir\"/* --outdir \"$csvDir\"";

    //there is an alternate solution requiring an additional step for file format conversion available at: https://superuser.com/questions/199799/vim-shows-strange-characters-91-92#

    system($cmd);
}

/**
 * create json files to mirror the csv files, but remove extraneous columns first
 */
function csv_to_clean_json($csvDir, $jsonDir){

    foreach (scandir($csvDir) as $file){
        if ($file=='.'||$file=='..')continue;
        // if ($file!='idph-cases.csv')continue;
        $jsonFileName = pathinfo($file, PATHINFO_FILENAME).'.json';

        echo "\nStart file '$file'\n   ";
        $path = $csvDir.'/'.$file;
        $csv = League\Csv\Reader::createFromPath($path, 'r');
        // row 9 has db column names
        // row 10 has spreadsheet column names (human friendly)
        // row 11 (offset 10) has first row of data
        $csv->setHeaderOffset(8); 
        $header = $csv->getHeader(); //returns the CSV header record

        $cols = [];
        foreach ($header as $index=>$colName){
            if (trim($colName)==''||substr($colName,0,2)=='--')break;
            $cols[] = $colName;
        }

        $json_out = [];
        $f = fopen($jsonPath=$jsonDir.'/'.$jsonFileName, 'w');
        if (!$f){
            throw new \Exception("Could not open ".$jsonPath);
        }
        fwrite($f, "[\n");
        $has_written = false;
        foreach ($csv->getRecords($cols) as $offset => $record){
            if ($offset<10)continue;
            $record = clean_row($cols,$record);
            if ($record == null)continue;
            if ($has_written) fwrite($f,','."\n");
            fwrite($f,json_encode($record));
            $has_written = true;
        }
        fwrite($f, "\n]");
        fclose($f);
    }


}

function json_to_sql($jsonDir, $sqlDir){

    $out = $sqlDir; // prefix for .json, -gen.json, .sql

    foreach (scandir($jsonDir) as $file){
        if ($file == '..' || $file == '.')continue;
        echo "\nGenerate sql for $file";
        $fname = pathinfo($file, PATHINFO_FILENAME);
        $tableName = str_replace(['-',' '],'_', $fname);
        $outDir = $sqlDir.'/'.$fname;
        if (!is_dir($outDir))mkdir($outDir);
        $source = $jsonDir.$file;
        $jsonToSql = new JSONToTable($source, $outDir);
        $jsonToSql->generateSchema(true);
        $jsonToSql->generateSql($tableName,true, 1024*1024*1024);
    }

}

/**
 *
 * @see clean_value()
 * @return an array with cleaned-up data
 */
function clean_row($cols, $row){
    if (trim($row[$cols[0]])==''
        ||trim($row[$cols[1]])=='')return null;
    $out = [];
    foreach ($row as $key=>$value){
        $value = clean_value($key,$value);
        $out[$key] = $value;
    }

    return $out;
}


/**
 * - Rounds percents to 2 decimal places & casts to float
 * - converts 'na', 'n/a', and empty string to null
 *
 * @param $key the key for the column
 * @param $value the value to modify
 *
 * @return a cleaned up version of the value (sometimes null)
 */
function clean_value($key, $value){
    if (substr($value,-1)=='%'){
        $value = (float)substr($value,0,-1);
        $value = round($value,2);
        // 2 decimal places & remove the %
    } else if ($value=='na'||$value=='n/a'){
        $value = null;
    } else if ($value === ''){
        $value = null;
    }

    return $value;
}


/**
 *
 * @param $sqlDir the root dir for taluf/json-to-table's output
 * @param $databasePath the sqlite database path
 */
function execute_sql($sqlDir, $databasePath){
    if (is_file($databasePath))unlink($databasePath);
    $pdo = new \PDO('sqlite:'.$databasePath);
    foreach (scandir($sqlDir) as $dir){
        if ($dir == '.' || $dir == '..')continue;
        $path = $sqlDir.'/'.$dir;
        if (!is_dir($path))continue;
        $pass = 0;
        echo "\nExec ".basename($dir).': ';
        false!==$pdo->exec(file_get_contents($path.'/sql-gen-create.sql')) && $pass++;
        $msg1 = print_r($pdo->errorInfo(),true);
        false!==$pdo->exec(file_get_contents($path.'/sql-gen-insert-0.sql')) && $pass++;
        $msg2 = print_r($pdo->errorInfo(),true);

        if ($pass == 2)echo "success";
        else {
            echo "fail(".$pass.")";
            echo "\n   - ".$msg1;
            echo "\n   - ".$msg2;
        }
    }
}