how can I parse php array like this:
$cars= array(
"Ford"=>array("C-Max"=>array("length"=>"4333","width"=>"1825","height"=>"1560"),"Escape"=>array("length"=>"4480","width"=>"1845","height"=>"1730")
,"Explorer"=>array("length"=>"4912","width"=>"1872","height"=>"1849"),"Fiesta"=>array("length"=>"3950","width"=>"1973","height"=>"1433")
,"Focus"=>array("length"=>"4488","width"=>"1840","height"=>"1497"),"Fusion"=>array("length"=>"4013","width"=>"1724","height"=>"1543")
,"Galaxy"=>array("length"=>"4820","width"=>"1854","height"=>"1723"),"Kuga"=>array("length"=>"4443","width"=>"1842","height"=>"1677")
,"Mondeo"=>array("length"=>"4844","width"=>"1886","height"=>"1500"),"Ranger"=>array("length"=>"5075","width"=>"1805","height"=>"1745")
,"S-Max"=>array("length"=>"4768","width"=>"1854","height"=>"1658"),
"Hummer"=>array("H2"=>array("length"=>"5170","width"=>"2063","height"=>"2012"),"H3"=>array("length"=>"4782","width"=>"1989","height"=>"1872")));
to insert into MySQL table like this:
CREATE TABLE IF NOT EXISTS `cars_dimensions` (
`id` int(10) NOT NULL auto_increment,
`brand` varchar(120) character set utf8 NOT NULL,
`model` varchar(120) character set utf8 NOT NULL,
`length` varchar(5) character set utf8 NOT NULL,
`width` varchar(5) character set utf8 NOT NULL,
`height` varchar(5) character set utf8 NOT NULL,
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
When I use foreach and like $cars["Hummer"]["H2"]["length"]; I somehow can't get another array dimension and cache the actual brand/model at the same time... Tho, my actual array is about 3000 items in the first dimension (brands).
You need two loops, one for the brands and one for their models:
foreach ($cars as $brand => $models) {
foreach ($models as $model => $specs) {
$query = "INSERT INTO cars_demensions (brand, model, length, weight, height)
VALUES ('$brand', '$model', {$specs['length']}, {$specs['width']}, {$specs['height']});";
}
}
foreach ( $cars as $brandname => $carinfo )
{
foreach ( $carinfo as $modelname => $car )
{
// brand = $brandname
// model = $modelname
// length = $car['length']
// do insert query here
}
}
$rows = '';
foreach($cars AS $brand) {
foreach($brand AS $model) {
if(!empty($rows)) $rows .= ', ';
$rows = "({$car['width']},...)";
}
}
$sql = "INSERT INTO cars_dimensions (width,...) VALUES $rows";
Full executable code and TESTED. This is more efficient and faster way to do this. Using this way you can insert multiple row using a single insert query.
<?php
$col = [];
foreach ($cars as $brand => $models) {
foreach ($models as $model => $specs) {
if (isset($specs['length']) || isset($specs['width']) || isset($specs['height'])) {
$length = $specs['length'];
$width = $specs['width'];
$height = $specs['height'];
} else {
foreach ($specs as $k => $v) {
$length = $v['length'];
$width = $v['width'];
$height = $v['height'];
}
}
$col[] = "('" . $brand . "', '" . $model . "', '" . $length . "', '" . $width . "', '" . $height . "')";
}
}
$query = "INSERT INTO `cars_dimensions`(`brand`, `model`, `length`, `width`, `height`) VALUES" . implode(',', $col) . ";";
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec($query);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
Hopefully it should help you. Thank you.
Related
The code I have worked except, it's only saving the first filename in the database. I want to be able to save them under img_path in one row separated by commas or | --->
img1.jpg, img2.jpg, img3.jpg
or
img123.jpg|img456.jpg|img789.jpg
Form:
<input type="file" name="img[]" multiple="" />
Here's the full code
<?php
$con = mysql_connect( 'localhost', '', '') or die('Could not connect to mysql server.' );
mysql_select_db('shop', $con) or die('Could not select database.');
$product=mysql_real_escape_string($_POST['product']);
$description=mysql_real_escape_string($_POST['description']);
$category=mysql_real_escape_string($_POST['category']);
$color=mysql_real_escape_string($_POST['color']);
$sizes=mysql_real_escape_string($_POST['sizes']);
$style=mysql_real_escape_string($_POST['style']);
$material=mysql_real_escape_string($_POST['material']);
$stock=mysql_real_escape_string($_POST['stock']);
$ws_price=mysql_real_escape_string($_POST['ws_price']);
$rt_price=mysql_real_escape_string($_POST['rt_price']);
$sp_code=mysql_real_escape_string($_POST['sp_code']);
foreach ($_FILES["img"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name =$_FILES["img"]["tmp_name"][$key];
//$tmp_name = implode(",", $_FILES["img"]["tmp_name"][$key]);
$name = $_FILES["img"]["name"][$key];
$rand = rand(0000,9999);
$px = $rand . $name;
$px = preg_replace('/\s+/','_', $px);
$px = str_replace('&', 'and', $px);
$target = 'img/'.$category.'/';
if (is_dir($target) == false) {
mkdir($target, 0755);
echo "Directory Created</br>";
}
$u = $target . $px;
move_uploaded_file($tmp_name, $u);
echo "". $px.", ";
$a = array($px);
$x = implode("|", $a);
}
}
$sql = "INSERT INTO items (
product, description, category, color, sizes, style, material, stock, ws_price, rt_price, sp_code, img_path
)VALUES(
'$product', '$description', '$category','$color','$sizes','$style','$material','$stock','$ws_price','$rt_price','$sp_code','$x'
)";
$result = mysql_query($sql);
if($result){ echo("<br>Product Added!"); }
else{ echo("<br>Failed! Please try again.");}
mysql_close($con);
?>
I've used this
$x = implode(',', $px)
$sql = "INSERT INTO items (img_path)VALUES('$x');";
and this
$sql = "INSERT INTO items (img_path)VALUES('". implode(',', $px)."')";
it would always give me an error.
Warning: implode(): Invalid arguments passed in [...]
Here's the solution I've come up with taking some suggestions here.
Instead of using implode to save them in img_path in the same table, I've created a new one which is img to save the image path and link them using pid (product_id) from the products (id) table.
Database
CREATE TABLE IF NOT EXISTS `img` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`img_path` varchar(255) NOT NULL,
`pid` int(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Here's the edited code (currently working... until I break it again XD):
<?php
$con=mysqli_connect("localhost","user","password","db");
if (mysqli_connect_errno($con)) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }
$product=mysql_real_escape_string($_POST['product']);
$description=mysql_real_escape_string($_POST['description']);
$category=mysql_real_escape_string($_POST['category']);
$color=mysql_real_escape_string($_POST['color']);
$sizes=mysql_real_escape_string($_POST['sizes']);
$style=mysql_real_escape_string($_POST['style']);
$material=mysql_real_escape_string($_POST['material']);
$stock=mysql_real_escape_string($_POST['stock']);
$ws_price=mysql_real_escape_string($_POST['ws_price']);
$rt_price=mysql_real_escape_string($_POST['rt_price']);
$sp_code=mysql_real_escape_string($_POST['sp_code']);
$sql = "INSERT INTO products (product, description, category, color, sizes, style, material, stock, ws_price, rt_price, sp_code)
VALUES('$product', '$description', '$category','$color','$sizes','$style','$material','$stock','$ws_price','$rt_price','$sp_code')";
if (!mysqli_query($con,$sql)){
die('Error: ' . mysqli_error($con));
} echo "<p>Product Added! </p>";
foreach ($_FILES["img"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name =$_FILES["img"]["tmp_name"][$key];
$name = $_FILES["img"]["name"][$key];
$rand = rand(0000,9999);
$px = $rand . $name;
$px = preg_replace('/\s+/','_', $px);
$px = str_replace('&', 'and', $px);
$px = str_replace("'", '-', $px);
$target = 'img/'.$category.'/';
if (is_dir($target) == false) {
mkdir($target, 0755);
echo "Directory Created</br>";
}
$u = $target . $px;
move_uploaded_file($tmp_name, $u);
echo "". $px."</br>";
mysqli_query($con,"INSERT INTO img (img_path, pid) VALUES ('$px', (SELECT MAX(id) FROM products))");
}
}
mysqli_close($con);
?>
I have a problem while uploading database with key-connection between the tables.
Script works well as far as there is no connection between the tables.
What MySql command do I have to include in my php class to drop all foreign keys ? So I'd be able to drop the tables and then after all tables have been created add the key-connection back onto the tables.
Here it is the class I am using:
<?php
class BackupDB
{
private $host = '';
private $username = '';
private $passwd = '';
private $dbName = '';
private $charset = '';
function __construct($host, $username, $passwd, $dbName, $charset = 'utf8')
{
$this->host = $host;
$this->username = $username;
$this->passwd = $passwd;
$this->dbName = $dbName;
$this->charset = $charset;
$this->initializeDatabase();
}
protected
function initializeDatabase()
{
$conn = mysql_connect($this->host, $this->username, $this->passwd);
mysql_select_db($this->dbName, $conn);
if (!mysql_set_charset($this->charset, $conn))
{
mysql_query('SET NAMES ' . $this->charset);
}
}
/**
* Backup the whole database or just some tables
* Use '*' for whole database or 'table1 table2 table3...'
* #param string $tables
*/
public
function backupTables($tables = '*', $outputDir = '.')
{
try
{
/**
* Tables to export
*/
if ($tables == '*')
{
$tables = array();
$result = mysql_query('SHOW TABLES');
while ($row = mysql_fetch_row($result))
{
$tables[] = $row[0];
}
}
else
{
$tables = is_array($tables) ? $tables : explode(',', $tables);
}
$sql = 'CREATE DATABASE IF NOT EXISTS ' . $this->dbName . ";\n\n";
$sql.= 'USE ' . $this->dbName . ";\n\n";
/**
* Iterate tables
*/
foreach($tables as $table)
{
echo "Backing up " . $table . " table...";
$result = mysql_query('SELECT * FROM ' . $table);
$numFields = mysql_num_fields($result);
$sql.= 'DROP TABLE IF EXISTS ' . $table . ';';
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE ' . $table));
$sql.= "\n\n" . $row2[1] . ";\n\n";
for ($i = 0; $i < $numFields; $i++)
{
while ($row = mysql_fetch_row($result))
{
$sql.= 'INSERT INTO ' . $table . ' VALUES(';
for ($j = 0; $j < $numFields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = str_replace("\n", "\\n", $row[$j]);
if (isset($row[$j]))
{
$sql.= '"' . $row[$j] . '"';
}
else
{
$sql.= '""';
}
if ($j < ($numFields - 1))
{
$sql.= ',';
}
}
$sql.= ");\n";
}
}
$sql.= "\n\n\n";
echo " OK" . "<br />";
}
}
catch(Exception $e)
{
var_dump($e->getMessage());
return false;
}
return $this->saveFile($sql, $outputDir);
}
/**
* Save SQL to file
* #param string $sql
*/
protected
function saveFile(&$sql, $outputDir = '.')
{
if (!$sql) return false;
try
{
$outputfilename = $outputDir . '/db-backup-' . $this->dbName . '-' . date("d.m.Y_H.i.s") . '.sql';
$result = mysql_query('INSERT INTO backuplog (backup) VALUES ("' . $outputfilename . '")');
$handle = fopen($outputfilename, 'w+');
fwrite($handle, $sql);
fclose($handle);
echo '<span class="message">Zapisano ' . $outputfilename . ' link do bazy. </span>';
echo '<span class="message">Właśnie pobrano kopie zapasową. Dziękujemy Serdecznie. Życzymy miłego dnia.</span>';
}
catch(Exception $e)
{
$result = mysql_query('DELETE FROM backuplog WHERE backup ="' . $outputfilename . '"');
var_dump($e->getMessage());
echo '<span class="error">Notacja.Udało się pobrać bazedanych... ale #NIE zaladowano linku do formularza, aby odzyskać dane trzeba ręcznie wpisać nazwę folderu/orazpliku.sql</span>';
echo '<span class="error">UWAGA! Wystąpił błąd podczas zapisywania danych w bazie... Zadanie nie ukończone.</span>';
return false;
}
return true;
} //end f
public
function loadDB($filename)
{
// $result=exec('mysql --user='.$this->user.' --password='.$this->pass .'<DatabaseBackUp/'.$filename);
// mysql -u user_name -p <file_to_read_from.sql
$templine = '';
// Read in entire file
$lines = file($filename);
// Loop through each line
foreach($lines as $line)
{
// Skip it if it's a comment
if (substr($line, 0, 2) == '--' || $line == '') continue;
// Add this line to the current segment
$templine.= $line;
// If it has a semicolon at the end, it's the end of the query
if (substr(trim($line) , -1, 1) == ';')
{
// Perform the query
if (!mysql_query($templine))
{
echo "Błąd ładownia pliku.sql";
return false;
} //echo $templine //TEST!
// Reset temp variable to empty
$templine = '';
}
}
return true;
} //end function
} //End calss
/* USE EXAMPLE
// DOWNLOAD DB FROM SERVER AS SQL FILE TO
$backupDatabase = new BackupDB(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$status = $backupDatabase->backupTables(TABLES, OUTPUT_DIR) ? 'OK' : 'KO';
echo "<br /><br /><br />Backup result: ".$status;
// RETRIVE DATA FROM SQL FILE TO DATABASE
$backupDatabase->loadDB("Path/to/mysqlfile.sql");
*/
?>
If you know how to extract foreign keys from a database, drop them one after the other, delete all tables and then put the keys back on again, please share your knowledge. Thanks again for looking into it.
Again for those who like to use this script it works fine... if! tables in database are not connected with foreign keys. Let's hope this state will soon change.
Short example of outputed .sql file:
CREATE DATABASE IF NOT EXISTS DATABASEONE;
USE DATABASEONE;
DROP TABLE IF EXISTS st_glowne_st_pages;
CREATE TABLE `st_glowne_st_pages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fk_glowne` varchar(50) COLLATE utf8_polish_ci NOT NULL,
`fk_pages` varchar(50) COLLATE utf8_polish_ci NOT NULL,
`kolejnosc` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`),
KEY `fk_glowne` (`fk_glowne`),
KEY `fk_pages` (`fk_pages`),
CONSTRAINT `st_glowne_st_pages_ibfk_1` FOREIGN KEY (`fk_glowne`) REFERENCES `st_glowne` (`name`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `st_glowne_st_pages_ibfk_2` FOREIGN KEY (`fk_pages`) REFERENCES `st_pages` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;
INSERT INTO st_glowne_st_pages VALUES("1","admin.php","pageadmin.php","1");
INSERT INTO st_glowne_st_pages VALUES("3","index.php","pageindex.php","1");
INSERT INTO st_glowne_st_pages VALUES("4","work.php","pagework.php","1");
INSERT INTO st_glowne_st_pages VALUES("7","register.php","pageregister.php","1");
INSERT INTO st_glowne_st_pages VALUES("8","login.php","pagelogin.php","1");
I haven't tried this myself, but apparently you can turn checking off.
SET FOREIGN_KEY_CHECKS = 0;
you'll need to read all the foreign key constraints and also store them in your backup file if you want to recreate them afterwards.
see this answer for some more clues.
you really should consider using sqldump though ...
I am parsing xml file from url(in code below), using file_get_contents() function, and simpleXML, to insert data into the table, i did well, but i have problem with encoding(russian words) i get this ->Черногория; file and database encoding is set to utf-8;
require_once 'mysql_connect.php';
/**
*
*
*/
error_reporting(E_ALL);
$sql = "CREATE TABLE IF NOT EXISTS `db_countries` (
`id` int(11) unsigned NOT NULL auto_increment,
`countrykey` varchar(255) NOT NULL default '',
`countryname` varchar(255) NOT NULL default '',
`countrynamelat` varchar(500) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
mysql_query($sql);
$data = file_get_contents("http://www2.turtess-online.com.ua/export/dictionary/countries/");
$xml = new SimpleXMLElement($data);
echo $xml->body->dictionary->element["countryName"];
foreach ($xml->body->dictionary->element as $element) {
$countryname = mysql_real_escape_string($element["countryName"]);
$countrynamelat = mysql_real_escape_string($element["countryNameLat"]);
$countrykey = $element["countryKey"];
if ($countrykey) {
$q = $insert = 'INSERT INTO db_countries (countrykey, countryname, countrynamelat) VALUES ("' . $countrykey . '", "' . $countryname . '", "' . $countrynamelat . '")';
mysql_query($q);
} else {
echo "not valid key of country";
}
}
Make sure you insert Unicode content as well, database charset is not doing any "automagic" conversion.
As an alternative, I would suggest utf8_encode($countryname) as in :
if ($countrykey) {
$q = $insert = 'INSERT INTO db_countries (countrykey, countryname, countrynamelat) VALUES ("' . $countrykey . '", "' . cp1251_to_utf8($countryname) . '", "' . $countrynamelat . '")';
mysql_query($q);
} else {
echo "not valid key of country";
}
update : indeed, the XML source file shows a Windows 1251 charset
UPDATE(2) : i tested the code against this nifty little function and it works at last :)
function cp1251_to_utf8($s)
{
if ((mb_detect_encoding($s,'UTF-8,CP1251')) == "WINDOWS-1251")
{
$c209 = chr(209); $c208 = chr(208); $c129 = chr(129);
for($i=0; $i<strlen($s); $i++)
{
$c=ord($s[$i]);
if ($c>=192 and $c<=239) $t.=$c208.chr($c-48);
elseif ($c>239) $t.=$c209.chr($c-112);
elseif ($c==184) $t.=$c209.$c209;
elseif ($c==168) $t.=$c208.$c129;
else $t.=$s[$i];
}
return $t;
}
else
{
return $s;
}
}
credit goes to Martin Petrov
I was able to connect to mysql db and create a table but there is no data and would like to know what i am missing or doing wrong? I have post my function code below. My echo count is confirmed and I also checked my Poems.csv to ensure they are not blank.
function writeQuotestoDb() {
$input_csv = fopen( "Poems.csv", "r" );
$author_names = array();
$poem_names = array();
$poem_urls = array();
while (($columns = fgetcsv($input_csv, 1000, ",")) !== FALSE) {
array_push( $author_names, $columns[0] );
array_push( $poem_names, $columns[1] );
array_push( $poem_urls, $columns[2] );
}
fclose( $input_csv );
$dbh = mysql_connect( 'localhost', 'root', '' );
mysql_select_db( 'test', $dbh );
mysql_query("CREATE TABLE IF NOT EXISTS `poem2` (
`id` INT( 20 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`author_name` varchar(128) DEFAULT NULL,
`poem_name` varchar(128) DEFAULT NULL,
`poem_text` text,
`poem_url` varchar(1024) DEFAULT NULL
) ENGINE = MYISAM");
mysql_query("TRUNCATE `poem2`");
for ( $i=0; $i<count($author_names); $i++ ) {
$poems[$i] = substr($poems[$i],7,(strlen($poems[$i])-14));
$poems[$i] = str_replace('"','',$poems[$i]);
$query = 'INSERT INTO `poem2` VALUES ( NULL,"' . $author_names[$i] . '", "' . $poem_names[$i].'","' . $poem_urls[$i] .'")';
mysql_query($query);
}
echo count($author_names)." rows....successfully db updated";
}
You are missing poem_text from your insert query. You can use the updated code below:
function writeQuotestoDb() {
$input_csv = fopen( "Poems.csv", "r" );
$author_names = array();
$poem_names = array();
$poem_urls = array();
while (($columns = fgetcsv($input_csv, 1000, ",")) !== FALSE) {
array_push( $author_names, $columns[0] );
array_push( $poem_names, $columns[1] );
array_push( $poem_urls, $columns[2] );
array_push( $poem_text, $columns[3] ); // If columns[3] does not exists you can just use array_push( $poem_text, '' );
}
fclose( $input_csv );
$dbh = mysql_connect( 'localhost', 'root', '' );
mysql_select_db( 'test', $dbh );
mysql_query("CREATE TABLE IF NOT EXISTS `poem2` (
`id` INT( 20 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`author_name` varchar(128) DEFAULT NULL,
`poem_name` varchar(128) DEFAULT NULL,
`poem_text` text,
`poem_url` varchar(1024) DEFAULT NULL
) ENGINE = MYISAM");
mysql_query("TRUNCATE `poem2`");
for ( $i=0; $i<count($author_names); $i++ ) {
$poems[$i] = substr($poems[$i],7,(strlen($poems[$i])-14));
$poems[$i] = str_replace('"','',$poems[$i]);
$query = 'INSERT INTO `poem2`(`author_name`, `poem_name`, `poem_text`, `poem_url`) VALUES ( "' . $author_names[$i] . '", "' . $poem_names[$i] . '", "' . $poem_text[$i] . '","' . $poem_urls[$i] .'")';
mysql_query($query);
}
echo count($author_names)." rows....successfully db updated";
}
If you don't want to insert poem_text then just use the following insert statement instead of your original insert query.
$query = 'INSERT INTO `poem2`(`author_name`, `poem_name`, `poem_url`) VALUES ( "' . $author_names[$i] . '", "' . $poem_names[$i] . '","' . $poem_urls[$i] .'")';
I have a database containing three tables:
practices - 8 fields
patients - 47 fields
exacerbations - 11 fields
The majority of the fields in these tables are recorded in varchar format, other fields include integers, doubles and dates.
I have to transform this data into numerically classified data so that it can be used by a statistician to extrapolate any patterns in the data. To acheive this I will have to convert varchar fields into integers that represent the classification that string belongs to, an example being 'Severity' which has the following possible string values:
Mild
Moderate
Severe
Very Severe
This field in the patients table has a finite list of string values that can appear, other fields have an endless possibility of string values that cannot be classified until they are encountered by my database (unless I implement some form of intelligent approach).
For the time being I am just trying to construct the best approach to converting each field for all entries in each of the 3 tables to numeric values. The pseudo code I have in my head so far is as follows (it's not complete):
function profileDatabase
for each table in database
for each field that is of type varchar
select all distinct values and insert into classfication table for that field
end for
end for
function classifyDatabase
for each table in database
for each field that is of type varchar
// do something efficient to build an insert string to place into new table
end for
end for
Can someone suggest the best way of performing this process so that it is efficient giving that there are currently in excess of 100 practices, 15,000 patients and 55,000 exacerbations in the system. I have no need to implement this in PHP, build I would prefer to do so. Any pointers as to how to structure this would be great as I am not sure my approach the best approach.
This process will have to run every month for the next two years as the database grows to have a total of 100,000 patients.
Maybe http://dev.mysql.com/doc/refman/5.1/en/procedure-analyse.html will help to get an overview to find out how fields are used.
I have managed to build my own solution to this problem which runs in reasonable time. For anyone interested, or anyone who may encounter a similar issue here is the approach I have used:
A PHP script that is run as a cron job by calling php scriptName.php [database-name]. The script builds a classified table for each table name that is within the database (that is not a lookup table for this process). The setting up of each classification creates a new table which mimics the format of the base table but sets all fields to allow NULL values. It then creates blank rows for each of the rows found in the base table. The process then proceeds by analysing each table field by field and updating each row with the correct class for this field.
I am sure I can optimise this function to improve on the current complexity, but for now I shall use this approach until the run-time of the scripts goes outside of an acceptable range.
Script code:
include ("../application.php");
profileDatabase("coco");
classifyDatabase("coco");
function profileDatabase($database) {
mysql_select_db($database);
$query = "SHOW TABLES";
$result = db_query($query);
$dbProfile = array();
while ($obj = mysql_fetch_array($result)) {
if (!preg_match("/_/", $obj[0])) {
$dbProfile[$obj[0]] = profileTable($obj[0]);
}
}
return $dbProfile;
}
function profileTable($table) {
$tblProfile = array();
$query = "DESCRIBE $table";
$result = db_query($query);
while ($obj = mysql_fetch_array($result)) {
$type = substr($obj[1], 0, 7);
//echo $type;
if (preg_match("/varchar/", $obj[1]) && (!preg_match("/Id/", $obj[0]) && !preg_match("/date/", $obj[0]) && !preg_match("/dob/", $obj[0]))) {
$x = createLookup($obj[0], $table);
$arr = array($obj[0], $x);
$tblProfile[] = $arr;
}
}
return $tblProfile;
}
function getDistinctValues($field, $table) {
$distinct = array();
$query = "SELECT DISTINCT $field as 'value', COUNT($field) as 'no' FROM $table GROUP BY $field ORDER BY no DESC";
$result = db_query($query);
while ($obj = mysql_fetch_array($result)) {
$distinct[] = $obj;
}
return $distinct;
}
function createLookup($field, $table) {
$query = "CREATE TABLE IF NOT EXISTS `" . $table . "_" . $field . "`
(
`id` int(5) NOT NULL auto_increment,
`value` varchar(255) NOT NULL,
`no` int(5) NOT NULL,
`map1` int(3) NOT NULL,
`map2` int(3) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1";
db_query($query);
$distinct = getDistinctValues($field, $table);
$count = count($distinct);
foreach ($distinct as $val) {
$val['value'] = addslashes($val['value']);
$rs = db_query("SELECT id FROM " . $table . "_" . $field . " WHERE value = '" . $val['value'] . "' LIMIT 1");
if (mysql_num_rows($rs) == 0) {
$sql = "INSERT INTO " . $table . "_" . $field . " (value,no) VALUES ('" . $val['value'] . "', " . $val['no'] . ")";
} else {
$sql = "UPDATE " . $table . "_" . $field . " (value,no) VALUES ('" . $val['value'] . "', " . $val['no'] . ")";
}
db_query($sql);
}
return $count;
}
function classifyDatabase($database) {
mysql_select_db($database);
$query = "SHOW TABLES";
$result = db_query($query);
$dbProfile = array();
while ($obj = mysql_fetch_array($result)) {
if (!preg_match("/_/", $obj[0])) {
classifyTable($obj[0]);
//echo "Classfied $obj[0]\n";
}
}
}
function classifyTable($table) {
$query = "SHOW TABLES";
$result = db_query($query);
$dbProfile = array();
$setup = true;
while ($obj = mysql_fetch_array($result)) {
if ($obj[0] == "classify_" . $table)
$setup = false;
}
if ($setup) {
setupClassifyTable($table);
//echo "Setup $table\n";
}
$query = "DESCRIBE $table";
$result = db_query($query);
while ($obj = mysql_fetch_array($result)) {
if (preg_match("/varchar/", $obj[1]) && (!preg_match("/Id/", $obj[0]) && !preg_match("/date/", $obj[0]) && !preg_match("/dob/", $obj[0]))) {
$rs = db_query("
SELECT t.entryId, t.$obj[0], COALESCE(tc.map1,99) as 'group' FROM $table t
LEFT JOIN " . $table . "_$obj[0] tc ON t.$obj[0] = tc.value
ORDER BY tc.map1 ASC");
while ($obj2 = mysql_fetch_object($rs)) {
$sql = "UPDATE classify_$table SET $obj[0] = $obj2->group WHERE entryId = $obj2->entryId";
db_query($sql);
}
} else {
if ($obj[0] != "entryId") {
$rs = db_query("
SELECT t.entryId, t.$obj[0] as 'value' FROM $table t");
while ($obj2 = mysql_fetch_object($rs)) {
$sql = "UPDATE classify_$table SET $obj[0] = '" . addslashes($obj2->value) . "' WHERE entryId = $obj2->entryId";
db_query($sql);
}
}
}
}
}
function setupClassifyTable($table) {
$tblProfile = array();
$query = "DESCRIBE $table";
$result = db_query($query);
$create = "CREATE TABLE IF NOT EXISTS `classify_$table` (";
while ($obj = mysql_fetch_array($result)) {
if (preg_match("/varchar/", $obj[1]) && (!preg_match("/Id/", $obj[0]) && !preg_match("/date/", $obj[0]) && !preg_match("/dob/", $obj[0]))) {
//echo $obj[1]. " matches<br/>";
$create .= "$obj[0] int(3) NULL,";
} else {
$create .= "$obj[0] $obj[1] NULL,";
}
}
$create .= "PRIMARY KEY(`entryId`)) ENGINE=MyISAM DEFAULT CHARSET=latin1";
db_query($create);
$result = mysql_query("SELECT entryId FROM $table");
while ($obj = mysql_fetch_object($result)) {
db_query("INSERT IGNORE INTO classify_$table (entryId) VALUES ($obj->entryId)");
}
}
?>