fannie/modules/plugins2.0/CoopCred/sync/SyncLanesForPlugin.php
<?php
/*******************************************************************************
Copyright 2013 Whole Foods Co-op
This file is part of Fannie.
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
*********************************************************************************/
/**
@class SyncLanesForPlugin
Clones SyncLanes at this point, redefines everything.
When issues sorted would like to replace $FCL2D/SyncLanes with this.
Supports syncing a single lane.
Uses extension .inc in sync/special instead of .php to avoid API scanning.
*/
class SyncLanesForPlugin extends COREPOS\Fannie\API\data\SyncLanes
{
/**
Do not truncate any tables
*/
const TRUNCATE_NONE = 0;
/**
Truncate the source table AFTER
copying it
*/
const TRUNCATE_SOURCE = 1;
/**
Truncate the destination table BEFORE
inserting into it
*/
const TRUNCATE_DESTINATION = 2;
/**
Copy a table from the server to the lanes
@param $table string table name
@param $db string 'op' or 'trans'
(default is 'op')
@param $truncate integer
(default is TRUNCATE_DESTINATION)
@param $one_lane integer
(default is 0, do all lanes
if > 0, the lane to do)
@return array
- sending => boolean attempted to copy table
- messages => string result information
*/
static public function pushTable($table,$db='op',
$truncate=self::TRUNCATE_DESTINATION,$one_lane=0)
{
global $FANNIE_OP_DB, $FANNIE_TRANS_DB, $FANNIE_LANES;
/* Only if needed.
global $FANNIE_PLUGIN_LIST, $FANNIE_PLUGIN_SETTINGS;
global $FANNIE_SERVER;
*/
$ret = array('sending'=>True,'messages'=>'');
$dbOrig = $db;
$db = strtolower($db);
if ($db != 'op' && $db != 'trans' && substr($db,0,7) != 'plugin:') {
$ret['sending'] = False;
$ret['messages'] = 'Invalid database: '.$db;
return $ret;
} elseif(empty($table)) {
$ret['sending'] = False;
$ret['messages'] = 'No table given';
return $ret;
} elseif (preg_match('/^[^A-Za-z0-9_]+$/',$table)) {
$ret['sending'] = False;
$ret['messages'] = 'Illegal table name: '.$table;
return $ret;
}
/* If the name of the db rather than the plugin is being passed,
* $dbOrig is not needed.
* $PLUGIN_LIST and $PLUGIN_SETTINGS not needed.
*/
$server_db = '';
$lane_db = '';
if (substr($db,0,7) == 'plugin:') {
$dbs = substr($db,7);
list($server_db,$lane_db) = explode('|',$dbs);
// Are these database-name checks really needed?
if(empty($server_db)) {
$ret['sending'] = False;
$ret['messages'] = 'No server database given';
return $ret;
} elseif (preg_match('/^[^A-Za-z0-9_]+$/',$server_db)) {
$ret['sending'] = False;
$ret['messages'] = 'Illegal database name: '.$server_db;
return $ret;
}
if(empty($lane_db)) {
$ret['sending'] = False;
$ret['messages'] = 'No lane database given';
return $ret;
} elseif (preg_match('/^[^A-Za-z0-9_]+$/',$lane_db)) {
$ret['sending'] = False;
$ret['messages'] = 'Illegal database name: '.$lane_db;
return $ret;
}
}
/* If the name of the plugin is being passed to here.
if (substr($db,0,7) == 'plugin:') {
$plugin = substr($dbOrig,7);
if (!in_array("$plugin",$FANNIE_PLUGIN_LIST)) {
$ret['sending'] = False;
$ret['messages'] = "Plugin: $plugin is not enabled.";
return $ret;
}
if (!isset($FANNIE_PLUGIN_SETTINGS["{$plugin}Database"])) {
$ret['sending'] = False;
$ret['messages'] = "Database for Plugin: $plugin is not assigned.";
return $ret;
}
$db = $FANNIE_PLUGIN_SETTINGS["{$plugin}Database"];
}
*/
// In the plugin/sync.
$special = dirname(__FILE__).'/special/'.$table.'.inc';
// If in $FCL2D path is different.
//$special = dirname(__FILE__).'/../../../sync/special/'.$table.'.php';
if (file_exists($special)) {
/* Use special script to send table.
* Usually with mysqldump.
* Much faster if both sides are mysql.
*/
ob_start();
$outputFormat = 'plain';
$tmp2="";
$tmp2 .= "In pushTable ";
$tmp2 .= (isset($one_lane)) ? "one_lane is set to {$one_lane}." :
"one_lane is not set. ";
include($special);
$tmp = ob_get_clean();
$ret = array('sending'=>True,'messages'=>'');
$ret['messages'] .= $tmp2;
$ret['messages'] .= $tmp;
return $ret;
} else {
$ret['messages'] .= "Doing by SQL Transfer\n";
/* use the transfer option in SQLManager
* to copy records onto each lane
*/
if ($db=='op') {
$server_db = $FANNIE_OP_DB;
} elseif ($db=='trans') {
$server_db = $FANNIE_TRANS_DB;
} else {
$noop = 0;
}
$ret['messages'] .= "server_db: $server_db lane_db: $lane_db \n";
$dbc = FannieDB::get( $server_db );
$laneNumber=0;
foreach($FANNIE_LANES as $lane) {
$laneNumber++;
if (isset($one_lane) && $one_lane > 0 && $laneNumber != $one_lane) {
$ret['messages'] .= "pushTable: skip {$laneNumber}";
continue;
}
// If writing to a non-standard db reassign $lane['op'] to it.
if ($lane_db != '') {
$db = 'op';
$lane[$db] = $lane_db;
/* Since lane and server db may not be the same this isn't needed.
if ($lane['host'] == $FANNIE_SERVER) {
// Message during development only.
$ret['messages'] .= "Lane $laneNumber ({$lane['host']}) " .
"Skipped lane on Fannie host: $FANNIE_SERVER \n";
continue;
}
*/
}
// This creates the lane-side DB if it doesn't exist.
$ret['messages'] .= "Before addConnection()\n";
$success = $dbc->addConnection($lane['host'],$lane['type'],
$lane[$db],$lane['user'],$lane['pw']);
if ($success) {
$ret['messages'] .= "After addConnection() OK\n";
} else {
$ret['messages'] .= "After addConnection() failed\n";
}
if ($dbc->connections[$lane[$db]]) {
if (!$dbc->tableExists($table,$lane[$db])) {
$ret['messages'] .=
("Lane $laneNumber ({$lane['host']}) $table does not exist.\n" .
" This utility cannot create destination tables " .
" but the fannie/sync/special utilties can.\n"
);
continue;
}
if ($truncate & self::TRUNCATE_DESTINATION) {
$success = $dbc->query("TRUNCATE TABLE $table",$lane[$db]);
}
if (!$success) {
$ret['messages'] .=
("Lane $laneNumber ({$lane['host']}) $table " .
"could not be truncated.\n" .
" Aborting sync of this table to this lane.\n");
continue;
}
$success = $dbc->transfer($server_db,
"SELECT * FROM $table",
$lane[$db],
"INSERT INTO $table");
$dbc->close($lane[$db]);
if ($success) {
$ret['messages'] .=
"Lane $laneNumber ({$lane['host']}) $table " .
"completed successfully. ";
} else {
$ret['messages'] .=
"Lane $laneNumber ({$lane['host']}) $table " .
"completed but with some errors. ";
}
} else {
$ret['messages'] .= "Couldn't connect to lane $laneNumber " .
"({$lane['host']}). ";
}
}
if ($truncate & self::TRUNCATE_SOURCE) {
$success = $dbc->query("TRUNCATE TABLE $table",$server_db);
if (!$success) {
$ret['messages'] .=
"Server $server_db table: $table could not be truncated.";
}
}
return $ret;
}
// pushTable()
}
static public function push_table($table,$db='op',
$truncate=self::TRUNCATE_DESTINATION,$one_lane=0)
{
return self::pushTable($table, $db, $truncate, $one_lane);
}
/**
Copy a table from the lanes to the server
@param $table string table name
@param $db string 'op' or 'trans'
(default is 'trans')
@param $truncate integer
(default is TRUNCATE_SOURCE)
@param $one_lane integer
(default is 0, do all lanes
if > 0, the lane to do)
@return array
- sending => boolean attempted to copy table
- messages => string result information
NOT USED IN COOP CRED, not tested.
*/
static public function pullTable($table,$db='trans',
$truncate=self::TRUNCATE_SOURCE,$one_lane=0)
{
global $FANNIE_OP_DB, $FANNIE_TRANS_DB, $FANNIE_LANES;
$ret = array('sending'=>True,'messages'=>'');
$db = strtolower($db);
if ($db != 'op' && $db != 'trans') {
$ret['sending'] = False;
$ret['messages'] = 'Invalid database: '.$db;
return $ret;
} elseif(empty($table)) {
$ret['sending'] = False;
$ret['messages'] = 'No table given';
return $ret;
} elseif (preg_match('/^[^A-Za-z0-9_]+$/',$table)) {
$ret['sending'] = False;
$ret['messages'] = 'Illegal table name: '.$table;
return $ret;
}
/* use the transfer option in SQLManager
* to copy records from each lane
*/
$server_db = $db=='op' ? $FANNIE_OP_DB : $FANNIE_TRANS_DB;
$dbc = FannieDB::get( $server_db );
if ($truncate & self::TRUNCATE_DESTINATION) {
$dbc->query("TRUNCATE TABLE $table",$server_db);
}
$laneNumber=1;
foreach($FANNIE_LANES as $lane) {
if (isset($one_lane) && $one_lane > 0 && $laneNumber != $one_lane) {
$ret['messages'] .= "pullTable: skip {$laneNumber}";
$laneNumber++;
continue;
}
$dbc->addConnection($lane['host'],$lane['type'],
$lane[$db],$lane['user'],$lane['pw']);
if ($dbc->connections[$lane[$db]]) {
$success = $dbc->transfer($lane[$db],
"SELECT * FROM $table",
$server_db,
"INSERT INTO $table");
if ($truncate & self::TRUNCATE_SOURCE) {
$dbc->query("TRUNCATE TABLE $table",$lane[$db]);
}
$dbc->close($lane[$db]);
if ($success) {
$ret['messages'] .= "Lane $laneNumber ({$lane['host']}) $table completed successfully";
} else {
$ret['messages'] .= "Lane $laneNumber ({$lane['host']}) $table completed but with some errors";
}
} else {
$ret['messages'] .= "Couldn't connect to lane $laneNumber ({$lane['host']})";
}
$laneNumber++;
}
return $ret;
// pullTable()
}
static public function pull_table($table,$db='trans',$truncate=self::TRUNCATE_SOURCE,$one_lane=0)
{
return self::pullTable($table, $db, $truncate,$one_lane);
}
}