fannie/classlib2.0/data/DataLoad.php
<?php
/*******************************************************************************
Copyright 2014 Whole Foods Co-op
This file is part of CORE-POS.
IT CORE is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
IT CORE 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 General Public License for more details.
You should have received a copy of the GNU General Public License
in the file license.txt along with IT CORE; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************************/
namespace COREPOS\Fannie\API\data {
class DataLoad
{
/**
Load sample data from fannie/install/sample_data
@param $sql [SQLManager] database connection
@param $table [string] table name
@param $search_dir [path, optional] look in different file
location for sample data files
@return [boolean] success
Sample data should be one of the following
1. A file named $table.csv with each line containing
a database record
2. A file named $table.sql with each line containing
a VALUES clauses (including parenthesis). The resulting
query will be:
INSERT INTO $table VALUES $line_from_file
*/
public static function loadSampleData($sql, $table, $search_dir='')
{
$loaded = 0;
$success = true;
if (empty($search_dir)) {
$search_dir = dirname(__FILE__) . '/../../install/sample_data/';
}
/**
Detect number of columns in table to ensure
dataset is complete. If the last column is autoincrement,
that value may be omitted.
*/
$table_def = $sql->detailedDefinition($table);
$valid_range = array(count($table_def), count($table_def));
$columns = array_keys($table_def);
$last_column = array_pop($columns);
if ($table_def[$last_column]['increment'] === true) {
$valid_range[0]--;
}
if (file_exists($search_dir . "/$table.sql")) {
echo " from $table.sql<br>\n";
$success = self::loadFromSql($table, $search_dir . '/' . $table . '.sql', $sql, $loaded);
} elseif (file_exists($search_dir . "/$table.csv")) {
$filename = realpath($search_dir . "/$table.csv");
$fptr = fopen($filename, 'r');
$first_line = fgetcsv($fptr);
fclose($fptr);
if (count($first_line) < $valid_range[0] || count($first_line) > $valid_range[1]) {
printf('Sample data for table %s has %d columns; should have between %d and %d columns',
$table, count($first_line),
$valid_range[0], $valid_range[1]);
return false;
}
echo " from $table.csv ";
if (self::loadFromCsv($table, $filename, $sql) !== false) {
echo " succeeded!<br>\n";
$loaded = 'All';
$success = true;
} else {
echo " line-by-line<br>\n";
$success = self::loadLinesFromCsv($table, $filename, $sql);
}
} else {
echo "<br><span style='color:red;'>Table data not found in either {$table}.sql or {$table}.csv</span><br>\n";
$success = false;
}
echo ($success? ' success!' : "<br>\n'$table' load " . ($loaded? 'partial success;' : 'failed;'))
. " $loaded " . ($loaded == 1? 'record was' : 'records were') . " loaded.<br>\n";
return $success;
}
private static function loadFromSql($table, $file, $sql, &$loaded=null)
{
echo " from $table.sql<br>\n";
$fptr = fopen($file, 'r');
$ret = true;
if (!is_null($loaded)) {
$loaded = 0;
}
while ($line = fgets($fptr)) {
$prep = $sql->prepare("INSERT INTO $table VALUES $line");
$try = $sql->execute($prep);
if ($try === false) {
$error = $sql->error();
$ret = false;
echo "<br><small style='color:red;'>"
. (strlen($error)? $error : 'Unknown error')
. " executing:<br><code>{$prep[0]}</code></small><br>\n";
} else {
if (!is_null($loaded)) {
$loaded++;
}
}
}
fclose($fptr);
return $ret;
}
private static function loadFromCsv($table, $file, $sql)
{
$fannie_host = \FannieConfig::factory()->get('SERVER');
$LOCAL = 'LOCAL';
if ($fannie_host == '127.0.0.1' || $fannie_host == 'localhost') {
$LOCAL = '';
}
$prep = $sql->prepare("LOAD DATA $LOCAL INFILE
'{$file}'
INTO TABLE $table
FIELDS TERMINATED BY ','
ESCAPED BY '\\\\'
OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\\r\\n'");
$try = $sql->execute($prep);
if ($try === false) {
$error = $sql->error();
echo "<br><span style='color:red;'>"
. (strlen($error)? $error : 'Unknown error')
. " executing:<br><code>{$prep[0]}</code><br></span><br>\n";
return false;
} else {
return true;
}
}
private static function loadLinesFromCsv($table, $file, $sql)
{
$fptr = fopen($file, 'r');
$stmt = false;
$ret = true;
while (!feof($fptr)) {
$line = fgetcsv($fptr);
if (!is_array($line)) continue;
if ($stmt === false) {
$query = 'INSERT INTO '.$table.' VALUES (';
foreach ($line as $field) {
$query .= '?,';
}
$query = substr($query,0,strlen($query)-1).')';
$stmt = $sql->prepare($query);
}
$try = $sql->execute($stmt, $line);
if ($try === false) {
$error = $sql->error();
$ret = false;
echo "<br><span style='color:red;'>"
. (strlen($error)? $error : 'Unknown error')
. " executing:<br><code>{$query}</code><br>("
. "'" . join("', '", $line) . "')"
. ' [' . count($line) . ' operands]'
. "</span><br>\n";
}
}
fclose($fptr);
return $ret;
}
}
}