Natty’s blog

Stay hungry. Stay foolish. — Steve Jobs

Archive for the ‘Foxpro’ Category

[PHP] Class สำหรับ convert DBF to MySQL

Posted by natty on September 22, 2008

เนื่องจากมีโปรเจคหนึ่งที่ต้องทำส่วนหนึ่ง คือส่วนของการ convert DBF to MySQL เลยเอามาฝากกัน ที่ทำเพราะว่า ระบบนี้จะเป็นต้องอ่าน DBF file ใหม่ๆ ทุกวันเพื่อนำมาใช้ในระบบ แต่ developer อยากใช้กับ MySQL database ดังนั้นเก๋จึงทำ class ที่อ่าน dbf file มาลง mysql ให้เค้า โดยทำเป็นตารางที่หน้าตาเหมือนกันใน MySQL ให้

ระบบนี้มี table ชื่อเดิม แต่ต้องอัพเดทข้อมูลตาม dbf file ทุกวัน ดังนั้นเก๋จึงไม่ได้ทำ function ที่ให้สร้าง MySQL table หน้าตาเหมือนๆ กัน ทำแค่ให้ insert ข้อมูลลงไปใน MySQL ได้ นั่นหมายความว่า หากต้องการนำ class นี้ไปใช้ ต้องสร้าง table ที่หน้าตาเหมือนกับ dbf file ไว้ก่อน แล้วค่อยเอา class นี้ไปช่วยในการ insert ข้อมูลให้

ใจจริง อยากทำ function ที่ให้ create table เหมือนกัน แต่ติดที่ว่า วิธีการอ่าน dbf file คือเก๋ใช้ dbase function ซึ่งเป็นการ read wirte dbf file แต่ไม่ใช่การ query ด้วยคำสั่ง SQL ดังนั้นจึงคิดวิธีการ get property ของ field ไม่ออก ว่าต้องทำยังงัย ก็เลยคิดว่า หากวันนึงอยากใช้ create table function ขึ้นมาจริงๆ คงต้องใช้ ODBC เข้าช่วย เพราะคำสั่ง SQL สามารถ get property ได้

มีไฟล์ที่เกี่ยวข้อง 3 ไฟล์ คือ DBFMySQL.php, iDBFMySQL.php และ test.php

เก๋กำหนดให้มี interface เอาไว้ จะเห็นว่า createTable โดน comment ไว้ แสดงว่ามันจะ coming soon ฮ่าๆ


<?php

/*created by Nattanicha Rittammanart
* Created date: Sep 22, 2008 */

interface iDBFMySQL{
    /*
        fromDBF: dbf with the right path
        toMySQL: define table name in MySQL
        myDB: MySQL database to put MySQL table
        myUser: MySQL username
        myPass: MySQL password
        myHost: MySQL Host

    */

    /**/
    public static function convertDBFToMySQL($fromDBF, $toMySQL, $myDB, $myUser, $myPass, $myHost);
    public static function readDBFToArray($fromDBF);
    public static function persistToMySQL($arrTable, $toMySQL, $myDB, $myUser, $myPass, $myHost);
    //public static function createMySQLTable($arrTable, $toMySQL, $myDB, $myUser, $myPass, $myHost);
}

function convertDBFToMySQL เป็นฟังก์ชั่นที่ให้ผู้ใช้เรียกใช้เพื่อ convert dbf to mysql โดยตรง โดยฟังก์ชั่นอื่น เป็นฟังก์ชั่นที่ใช้งานร่วมกับมันเท่านั้น ก็คือใส่ parameters ให้ครบ มันก็จะให้สิ่งที่ต้องการออกมา ฟังก์ชั่นนี้ เรียก readDBFToArray และ persistToMySQL มาใช้งาน


    public static function convertDBFToMySQL($fromDBF, $toMySQL, $myDB, $myUser, $myPass, $myHost){
        $arrTable = array();
        $arrTable = DBFMySQL::readDBFToArray($fromDBF);
        DBFMySQL::persistToMySQL($arrTable, $toMySQL, $myDB, $myUser, $myPass, $myHost);
    }

function readDBFToArray รับ path ของ dbf file เพื่อเอามาใส่ลง array โดยจะ return เป็น array 2 ชุดใหญ่ คือ ชุด column name กับชุดของ data โดยชุดของ data ก็จะเก็บเป็น array ย่อยลงไปอีก โดย array นี้จะ prepare เอาไว้ให้ function persistToMySQL เป็นคนเรียก


public static function readDBFToArray($fromDBF){
		// open in read-only mode
		$db = dbase_open($fromDBF, 0);
		$records = array();

		if ($db) {
		// read some data ..
			$record_numbers = dbase_numrecords($db);
			$field_numbers = dbase_numfields($db);
			for ($i = 1; $i <= $record_numbers; $i++) {
				$row = dbase_get_record_with_names($db, $i);
				array_push($records,array_values($row));
			}
			$columnHeader = array_keys($row);
			$arrTable = array($columnHeader,$records);
			dbase_close($db);
		}
		return $arrTable;
	}

function persistToMySQL รับ array มาจาก readDBFToArray เพื่อนำมาลง MySQL table ใน field ที่ถูกต้อง

public static function persistToMySQL($arrTable, $toMySQL, $myDB, $myUser, $myPass, $myHost){

		$connect = mysql_connect($myHost, $myUser, $myPass) or die("cannot connect to database");
		mysql_select_db($myDB, $connect);

		$columnHeader = $arrTable[0];
		$records = $arrTable[1];

		for($i=0;$i<sizeof($columnHeader)-1;$i++){
				$temp = $columnHeader[$i].",";
				$prepareFields=$prepareFields.$temp;
		}

		$prepareFields = substr($prepareFields, 0, -1);

		for($j=0;$j<sizeof($records);$j++){
			$prepareRecords='';
			for($i=0;$i<sizeof($records[$j])-1;$i++){
				$temp = "'".trim($records[$j][$i])."'".",";
				$prepareRecords=$prepareRecords.$temp;
			}
			$prepareRecords = substr($prepareRecords, 0, -1);
			$sql = "INSERT INTO $toMySQL ($prepareFields) VALUES ($prepareRecords)";
			$test = mysql_query($sql);
		}
	}

วิธีการใช้งานก็ง่ายมากๆ เลย ทำแบบนี้

<?php

/*created by Nattanicha Rittammanart
* Created date: Sep 22, 2008 */

include 'DBFMySQL.php';

$fromDBF='D:\PO_McDonald\INVORDD0.DBF';
$toMySQL='INVORDD0';
$myDB='db_mcdonald';
$myUser='root';
$myPass='root';
$myHost='localhost';

DBFMySQL::convertDBFToMySQL($fromDBF, $toMySQL, $myDB, $myUser, $myPass, $myHost);

?> 

ในอนาคตอาจจะมีการเพิ่มเติมฟังก์ชั่นเข้าไปอีกค่ะ หากเป็นประโยชน์ก็ช่วยบอกด้วยนะคะ

ดาวน์โหลด sourcecode ได้ที่นี่ ค่ะ

Posted in Foxpro, PHP | 1 Comment »

PHP+Foxpro: การ query date

Posted by natty on September 17, 2008

จากตอนที่แล้ว เรื่องของ Apache + PHP + GD lib + Foxpro + JPGraph ก็มาดูกันต่อในเรื่องการ query date ของ foxpro

จะยกตัวอย่างฟิลด์ date ที่เก็บเป็น yyyy/mm/dd

สมมติว่าเรา query date ขึ้นมา


$sql = "SELECT data_date FROM tablename;
$rs=odbc_exec($conn,$sql);
        if (!$rs)
            {exit("Error in SQL");}
        while (odbc_fetch_row($rs))
        {
            $data_date = odbc_result($rs,"data_date");
        }

หากเราต้องการนำข้อมูล date ดังกล่าวไป query ต่อ สิ่งที่ต้องทำคือ ต้องเปลี่ยน format ของ date นั้นเป็น mm/dd/yyyy เนื่องจากเรากำลังจะใช้คำสั่งในการ query date ของ foxpro คือคำสั่ง ctod (character to date) ซึ่งโดยปกติหากเราต้องการใช้ format ของวันที่ยังคงเป็น yyyy/mm/dd เราจะมีการใช้คำสั่ง set century on ก่อน แต่เนื่องจากเราไม่ได้ใช้คำสั่งนี้ใน PHP เราเลยต้อง parse date ดังกล่าวออกมาเป็น character เพื่อประกอบกับไปให้ได้ตาม mm/dd/yyyy และใช้คำสั่ง ctod ได้

(*หมายเหตุ ใน foxpro มีคำสั่งที่คล้าย ctod คือ dtoc (date to character))

สิ่งที่เราจะได้จาก $data_date คือข้อมูล date โดยที่เราสามารถ parse ออกมาได้ดังนี้


$dateparse = date_parse($data_date);
$month = $dateparse ["month"];
$day = $dateparse ["day"];
$year = $dateparse ["year"];

หากเราต้องการนำข้อมูล date ดังกล่าวไป query ต่อแบบไม่ใช้ set century on ทำได้ดังนี้


$sql = "SELECT * FROM tablename WHERE data_date >= ctod('" .$month. "/" .$day. "/" .$year. "')";

เพียงเท่านี้เราก็จะหมดปัญหาการ query date ของ foxpro

Posted in Foxpro, PHP | Leave a Comment »