CVS: phpweather/db pw_db_common.php,1.12,1.13 pw_db_dba.php,1.8,1.9 p...
Brought to you by:
iridium
From: Martin G. <gim...@us...> - 2002-08-28 10:05:58
|
Update of /cvsroot/phpweather/phpweather/db In directory usw-pr-cvs1:/tmp/cvs-serv12005 Modified Files: pw_db_common.php pw_db_dba.php pw_db_mysql.php pw_db_null.php pw_db_pgsql.php Log Message: Applied patches from Ondrej Jombik <ne...@po...> - I've changed them a little from what was sent to the mailing list. The lookup_icao($icao) method now returns an three element array with the name of the station, the name of the country, and the country code. The new functions get_name($icao), get_country($icao), and get_country_code($icao) are convenience functions that return what you think they return :-) The stations.db file has been regenerated to reflect the changes in the pw_db_null class. Index: pw_db_common.php =================================================================== RCS file: /cvsroot/phpweather/phpweather/db/pw_db_common.php,v retrieving revision 1.12 retrieving revision 1.13 diff -u -3 -r1.12 -r1.13 --- pw_db_common.php 26 Aug 2002 13:16:26 -0000 1.12 +++ pw_db_common.php 28 Aug 2002 10:05:55 -0000 1.13 @@ -3,6 +3,30 @@ require_once(PHPWEATHER_BASE_DIR . '/base_object.php'); /** + * The character used to seperate values in combined fields, if the + * database uses combined fields. The pw_db_null and pw_db_dba + * databases use this. + * + * @const PW_FIELD_SEPERATOR The field seperator. + * @access private + * @see PW_FIELD_REPLACEMENT + */ +define('PW_FIELD_SEPERATOR', ':'); + + +/** + * The character used to replace PW_FIELD_SEPERATOR in combined + * fields, if the database uses combined fields. The pw_db_null and + * pw_db_dba databases use this. + * + * @const PW_FIELD_REPLACEMENT The field seperator replacement. + * @access private + * @see PW_FIELD_SEPERATOR + */ +define('PW_FIELD_REPLACEMENT', ';'); + + +/** * Common class for all the database-types. * * It contains some properties most database-types need, like @@ -14,7 +38,8 @@ class pw_db_common extends base_object { /** - * Maintains the status of the database-connection. + * Maintains the status of the database-connection, if needed by the + * database backend. * * @var boolean * @access public @@ -22,7 +47,8 @@ var $is_connected; /** - * contains the link_id used when querying. + * Contains the link ID used when querying, if the database backend + * knows about a link ID. * * @var integer * @access private @@ -30,7 +56,8 @@ var $link_id; /** - * contains the result_id used when fetching rows from a result-set. + * Contains the result ID used when fetching rows from a result-set + * if the database backend knows about a result ID. * * @var integer * @access private @@ -131,6 +158,63 @@ fclose($fp); } + + + /** + * Returns the name of the station associated with an ICAO. + * + * @param string ICAO of the station. + * @return string the name of the station, i.e 'Tirstrup' for + * EKAH. If the ICAO doesn't exist in the database + * false is returned. + * @access public + */ + function get_name($icao) { + $data = $this->lookup_icao($icao); + if (empty($data)) { + return false; + } else { + return $data[0]; + } + } + + + /** + * Returns the name of the country associated with an ICAO. + * + * @param string ICAO of the station. + * @return string the name of the associated country, if it's + * available, otherwise return false. + * @access public + */ + function get_country($icao) { + $data = $this->lookup_icao($icao); + if (empty($data)) { + return false; + } else { + return $data[1]; + } + } + + + /** + * Returns country code associated with an ICAO. + * + * @param string ICAO of the station. + * @return string country code (cc) for passed station (ICAO) if + * available, false otherwise + * @access public + */ + function get_country_code($icao) { + $data = $this->lookup_icao($icao); + if (empty($data)) { + return false; + } else { + return $data[2]; + } + } + + } ?> Index: pw_db_dba.php =================================================================== RCS file: /cvsroot/phpweather/phpweather/db/pw_db_dba.php,v retrieving revision 1.8 retrieving revision 1.9 diff -u -3 -r1.8 -r1.9 --- pw_db_dba.php 26 Aug 2002 13:17:09 -0000 1.8 +++ pw_db_dba.php 28 Aug 2002 10:05:55 -0000 1.9 @@ -141,9 +141,10 @@ /** * Inserts a METAR into the database. * - * Any colons (:) in the METAR is changed into semi-colons (;). The - * colons has nothing to do in the body of the METAR, so this wont - * effect the parsing as the remarks isn't parsed anyway. + * Any instances of PW_FIELD_SEPERATOR (:) in the METAR is changed + * into PW_FIELD_REPLACEMENT (;). The colons has nothing to do in + * the body of the METAR, so this wont effect the parsing as the + * remarks isn't parsed anyway. * * @param string The ICAO of the station. * @param string The raw METAR. @@ -152,16 +153,20 @@ * @see update_metar() */ function insert_metar($station, $metar, $timestamp) { - $this->debug("Inserting this row into the DBA database:<br><code>$metar:$timestamp</code>"); - dba_insert($station, strtr($metar, ':', ';') . ':' . $timestamp, $this->link_id); + $row = strtr($metar, PW_FIELD_SEPERATOR, PW_FIELD_REPLACEMENT) . + PW_FIELD_SEPERATOR . $timestamp; + $this->debug("Inserting this row into the DBA database: <br><code>$row</code>"); + dba_insert($station, $row, $this->link_id); } + /** * Updates an existing METAR in the database. * - * Any colons (:) in the METAR is changed into semi-colons (;). The - * colons has nothing to do in the body of the METAR, so this wont - * effect the parsing as the remarks isn't parsed anyway. + * Any instances of PW_FIELD_SEPERATOR (:) in the METAR is changed + * into PW_FIELD_REPLACEMENT (;). The colons has nothing to do in + * the body of the METAR, so this wont effect the parsing as the + * remarks isn't parsed anyway. * * @param string The ICAO of the station. * @param string The raw METAR. @@ -170,10 +175,13 @@ * @see insert_metar() */ function update_metar($station, $metar, $timestamp) { - $this->debug("Updating this row in the DBA database:<br><code>$metar:$timestamp</code>"); - dba_replace($station, strtr($metar, ':', ';') . ':' . $timestamp, $this->link_id); + $row = strtr($metar, PW_FIELD_SEPERATOR, PW_FIELD_REPLACEMENT) . + PW_FIELD_SEPERATOR . $timestamp; + $this->debug("Updating this row in the DBA database:<br><code>$row</code>"); + dba_replace($station, $row, $this->link_id); } + /** * Gets a METAR form the database. * @@ -186,32 +194,34 @@ if (dba_exists($station, $this->link_id)) { $row = dba_fetch($station, $this->link_id); $this->debug("Returning this row from the DBA database:<br><code>$row</code>"); - return explode(':', $row); + return explode(PW_FIELD_SEPERATOR, $row); } else { return false; } } + /** - * Translates an ICAO into a station name - * - * The boring ICAO (e.g. EKYT) is translated into something like - * 'Aalborg, Denmark'. + * Fetches information about an ICAO. * * @param string The ICAO one want's to translate. - * @return string The full name of the station, including country. + * @return array If the ICAO was found, then the array will + * contain three entries: the name of the station, + * the name of the country, the country code of the + * country. If the ICAO wasn't found, then false is + * returned. * @access public */ function lookup_icao($icao) { if (dba_exists($icao, $this->link_stations_id)) { - list($name, $country) = - explode(':', dba_fetch($icao, $this->link_stations_id)); - return "$name, $country"; + return explode(PW_FIELD_SEPERATOR, + dba_fetch($icao, $this->link_stations_id)); } else { - return $icao; + return false; } } + /** * Creates the necessary files. * @@ -264,30 +274,36 @@ * It is assumed that create_tables() has been called previously * (and that it returned true). * - * @param array This three-dimensional array starts with a list of - * contry-codes. For each country-code the ICAOs and corresponding - * locations in that particular country are listed as key => value - * pairs. - * @param array An associative array with country-codes as the keys - * and the names of the countries as the values. + * @param array This three-dimensional array starts with a list of + * contry-codes. For each country-code the ICAOs and + * corresponding locations in that particular country + * are listed as key => value pairs. + * + * @param array An associative array with country-codes as the keys + * and the names of the countries as the values. + * * @return bool * @access private */ function insert_stations($data, $countries) { while(list($cc, $country) = each($countries)) { while(list($icao, $location) = each($data[$cc])) { - /* We insert all the stations in a given country into the - database. */ - dba_insert($icao, "$location:$country", $this->link_stations_id); + /* We insert all the stations together with the name of the + country and country code into the database. */ + dba_insert($icao, + $location . PW_FIELD_SEPERATOR . + $country . PW_FIELD_SEPERATOR . $cc, + $this->link_stations_id); $icaos[] = $icao; /* We collect the ICAOs for later. */ } /* Now that we've collected all the ICAOs in the country, lets insert the country with it's data into the database. The name - of the country is seperated from the list of ICAOs by a - single semi-colon (;). The ICAOs are seperated by a normal - colon (:). */ + of the country is seperated from the list of ICAOs by + PW_FIELD_SEPERATOR (:). The ICAOs are also seperated by + PW_FIELD_SEPERATOR. */ dba_insert($cc, - $country . ';' . implode(':', $icaos), + $country . PW_FIELD_SEPERATOR . + implode(PW_FIELD_SEPERATOR, $icaos), $this->link_countries_id); unset($icaos); /* We can now forget about the ICAOs. */ } @@ -309,9 +325,11 @@ $cc = dba_firstkey($this->link_countries_id); /* We need the first key. */ while ($data = dba_fetch($cc, $this->link_countries_id)) { - list($country) = explode(';', $data); - /* The above statement extracts the name of the country. It's - seperated from the ICAOs by a semi-colon (;) */ + /* This statement extracts the name of the country. It's + seperated from the ICAOs by PW_FIELD_SEPERATOR and after it + comes a list of ICAOs also seperated by the + PW_FIELD_SEPERATOR character: */ + list($country) = explode(PW_FIELD_SEPERATOR, $data, 2); $countries[$cc] = $country; $cc = dba_nextkey($this->link_countries_id); } @@ -341,16 +359,20 @@ } /* The name of the country is seperated from the list of ICAOs by - * a single semi-colon (;) */ - list($country, $icaos) = - explode(';', dba_fetch($cc, $this->link_countries_id)); - - /* The ICAOs are seperated by a normal colon (:) */ - $icaos = explode(':', $icaos); - while (list(, $icao) = each($icaos)) { - list($location) = - explode(':', dba_fetch($icao, $this->link_stations_id)); - $locations[$icao] = $location; + * PW_FIELD_SEPERATOR (:). The name is followed by a list of ICAOs + * which are also seperated by PW_FIELD_SEPERATOR. */ + $data = explode(PW_FIELD_SEPERATOR, + dba_fetch($cc, $this->link_countries_id)); + + /* The first entry is the country: */ + $country = array_shift($data); + + /* The remaining entries are the ICAOs: */ + while (list(, $icao) = each($data)) { + list($name) = + explode(PW_FIELD_SEPERATOR, + dba_fetch($icao, $this->link_stations_id)); + $locations[$icao] = $name; } asort($locations); Index: pw_db_mysql.php =================================================================== RCS file: /cvsroot/phpweather/phpweather/db/pw_db_mysql.php,v retrieving revision 1.5 retrieving revision 1.6 diff -u -3 -r1.5 -r1.6 --- pw_db_mysql.php 20 May 2002 15:48:48 -0000 1.5 +++ pw_db_mysql.php 28 Aug 2002 10:05:55 -0000 1.6 @@ -3,7 +3,7 @@ require_once(PHPWEATHER_BASE_DIR . '/db/pw_db_common.php'); /** - * This class is the 'mysql' database-type. + * This class is the 'mysql' database backend. * * It implements all the methods necessary to insert, update and * retrive METARs using a MySQL database. You'll need access to a @@ -184,9 +184,10 @@ * @see update_metar() */ function insert_metar($icao, $metar, $timestamp) { - $this->query("INSERT INTO " . $this->properties['db_metars'] . - " SET icao = '$icao', metar = '" . addslashes($metar) . "', " . - "timestamp = FROM_UNIXTIME($timestamp)"); + $this->query(sprintf('INSERT INTO %s SET icao = "%s", ' . + 'metar = "%s", timestamp = FROM_UNIXTIME(%d)', + $this->properties['db_metars'], $icao, + addslashes($metar), intval($timestamp))); } @@ -200,10 +201,11 @@ * @see insert_metar() */ function update_metar($icao, $metar, $timestamp) { - $this->query("UPDATE " . $this->properties['db_metars'] . - " SET metar = '" . addslashes($metar) . "', " . - "timestamp = FROM_UNIXTIME($timestamp) " . - "WHERE icao = '$icao'"); + $this->query(sprintf('UPDATE %s' . + ' SET metar = "%s", timestamp = FROM_UNIXTIME(%d)' . + ' WHERE icao = "%s"', + $this->properties['db_metars'], addslashes($metar), + intval($timestamp), $icao)); } @@ -215,8 +217,9 @@ * @access public */ function get_metar($icao) { - $this->query("SELECT metar, UNIX_TIMESTAMP(timestamp) FROM " . - $this->properties['db_metars'] . " WHERE icao = '$icao'"); + $this->query(sprintf('SELECT metar, UNIX_TIMESTAMP(timestamp)' . + ' FROM %s WHERE icao = "%s"', + $this->properties['db_metars'], $icao)); return $this->fetch_row(); } @@ -232,7 +235,7 @@ if (!$this->connect()) { return false; // Failure! } - + /* First we make a table for the METARs */ $this->query('DROP TABLE IF EXISTS ' . $this->properties['db_metars']); $this->query('CREATE TABLE ' . $this->properties['db_metars'] . '( @@ -253,28 +256,29 @@ UNIQUE icao (icao), KEY cc (cc))'); - return true; // Succes! + return true; // Success! } /** - * Translates an ICAO into a station name + * Fetches information about an ICAO. * - * The boring ICAO (e.g. EKYT) is translated into something like - * 'Aalborg, Denmark'. + * The array returned contains three entries: the name of the + * station, the name of the country, the country code of the + * country. * * @param string The ICAO one want's to translate. - * @return string The full name of the station, including country. + * @return array Information about the ICAO or false if no + * information is available. * @access public */ function lookup_icao($icao) { - $this->query('SELECT name, country FROM ' . - $this->properties['db_stations'] . " WHERE icao = '$icao'"); + $this->query(sprintf('SELECT name, country, cc FROM %s WHERE icao = "%s"', + $this->properties['db_stations'], addslashes($icao))); if ($this->num_rows() == 1) { - $row = $this->fetch_row(); - return "$row[0], $row[1]"; + return $this->fetch_row(); } else { - return $icao; + return false; } } @@ -305,8 +309,10 @@ while(list($icao, $location) = each($data[$cc])) { /* The station name might also be dangerous. */ $location = addslashes($location); - $this->query('INSERT INTO ' . $this->properties['db_stations'] . - " VALUES ('$icao', '$location', '$cc', '$country')"); + $this->query(sprintf('INSERT INTO %s VALUES ("%s", "%s", "%s", "%s")', + $this->properties['db_stations'], + $icao, addslashes($location), + addslashes($cc), addslashes($country))); } } @@ -325,7 +331,7 @@ if (!$this->connect()) { return false; } - + $this->query('SELECT DISTINCT cc, country FROM ' . $this->properties['db_stations'] . ' ORDER BY country'); while($row = $this->fetch_row()) { @@ -333,27 +339,30 @@ } return $rows; } - + /** * Returns an array of stations. * - * @param string The country-code. - * @param string This parameter is passed by reference. The name of - * the country that corresponds to the country-code is stored here. - * @return array An associative array with the ICAO as the key and - * the name of the station as the values. The name of the country is - * not added to the name of the station. + * @param string The country-code. + * @param string This parameter is passed by reference. The name of + * the country that corresponds to the country-code + * is stored here. + * @return array An associative array with the ICAO as the key and + * the name of the station as the values. The name + * of the country is not added to the name of the + * station. * @access public */ function get_icaos($cc, &$country) { if (!$this->connect()) { return false; } - - $this->query('SELECT icao, name, country FROM ' . - $this->properties['db_stations'] . - " WHERE cc = '$cc' ORDER BY name"); + + $this->query(sprintf('SELECT icao, name, country FROM %s' + .' WHERE cc = "%s" ORDER BY name', + $this->properties['db_stations'], + addslashes($cc))); /* We have to do this manually the first time, so that we can set $country */ list($icao, $name, $country) = $this->fetch_row(); Index: pw_db_null.php =================================================================== RCS file: /cvsroot/phpweather/phpweather/db/pw_db_null.php,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- pw_db_null.php 28 May 2002 13:26:15 -0000 1.3 +++ pw_db_null.php 28 Aug 2002 10:05:55 -0000 1.4 @@ -3,6 +3,15 @@ require_once(PHPWEATHER_BASE_DIR . '/db/pw_db_common.php'); /** + * Each line in the stations database will be padded with spaces to + * this length. to facilitate fast binary search. + * + * @const PW_LINE_LENGTH The length of lines in the stations database. + * @access private + */ +define('PW_LINE_LENGTH', 128); + +/** * This class is the 'null' database-type * * It pretends to be a database, but really it isn't :-) It just @@ -14,7 +23,7 @@ * @version $Id$ */ class pw_db_null extends pw_db_common { - + /** * This constructor does nothing besides calling the parent constructor. * @@ -80,8 +89,8 @@ * Pretends to return a METAR form the database. * * @param string The ICAO of the station. - * @return string Since we don't have a database, we just return an - * empty string. + * @return string Since we don't have a database, we just return an + * empty string. * @access public */ function get_metar($station) { @@ -89,34 +98,42 @@ } /** - * Translates an ICAO into a station name + * Fetches information about an ICAO. * - * @param string The ICAO to translate. - * @return string The translated ICAO. + * @param string The ICAO one want's to translate. + * @return array If the ICAO was found, then the array will + * contain three entries: the name of the station, + * the name of the country, the country code of the + * country. If the ICAO wasn't found, then false is + * returned. * @access public */ function lookup_icao($icao) { - $linesize = 128; - $fp = fopen(PHPWEATHER_BASE_DIR . '/db/files/stations.db', 'r'); - - $result = ''; + $size = filesize(PHPWEATHER_BASE_DIR . '/db/files/stations.db'); + + $result = false; // Default result. $left = 0; - $right = filesize(PHPWEATHER_BASE_DIR . '/db/files/stations.db')/$linesize; + $right = $size / PW_LINE_LENGTH; + /* We make a binary search for the right ICAO. The search + * terminates when $right >= $left: */ while ($left < $right) { - fseek($fp, $linesize * round(($left+$right)/2)); + fseek($fp, PW_LINE_LENGTH * round(($left+$right)/2)); - $data = fgetcsv($fp, $linesize, ';'); + /* Each line contains four fields seperated by + * PW_FIELD_SEPERATOR. The fields are: the ICAO, name of + * station, name of country, and country code. */ + $data = fgetcsv($fp, PW_LINE_LENGTH, PW_FIELD_SEPERATOR); if ($data[0] > $icao) { $right = floor(($left+$right)/2); } elseif ($data[0] < $icao) { $left = ceil(($left+$right)/2); } else { $left = $right; - $result = trim($data[1]); + $result = array($data[1], $data[2], $data[3]); } } fclose($fp); @@ -158,32 +175,39 @@ function insert_stations($data, $countries) { while(list($cc, $country) = each($countries)) { $fp = fopen(PHPWEATHER_BASE_DIR . "/db/files/$cc.php", 'w'); + if (!$fp) return false; + fputs($fp, "<?php\n/* File with stationnames in $countries[$cc] */\n\n"); fputs($fp, "\$country = '" . addslashes($countries[$cc]) . "';\n\n"); fputs($fp, "\$icaos = array(\n"); /* We do it ourselves the first time */ list($icao, $location) = each($data[$cc]); fputs($fp, " '$icao' => '" . addslashes($location) . "'"); - $stations[$icao] = "$location, $countries[$cc]"; + $stations[$icao] = array($location, $countries[$cc], $cc); while(list($icao, $location) = each($data[$cc])) { fputs($fp, ",\n '$icao' => '" . addslashes($location) . "'"); - $stations[$icao] = "$location, $countries[$cc]"; + $stations[$icao] = array($location, $countries[$cc], $cc); } fputs($fp, "\n);\n\n?>\n"); fclose($fp); } - /* We write a file with all the stations. Each line is 128 bytes - long so that it's easy to find a given station again. */ + /* We write a file with all the stations. Each line is + PW_LINE_LENGTH bytes long so that it's easy to find a given + station again. */ $fp = fopen(PHPWEATHER_BASE_DIR . '/db/files/stations.db', 'w'); if ($fp) { ksort($stations); reset($stations); - while(list($icao, $location) = each($stations)) { - $str = str_pad("$icao;$location", 127)."\n"; + while(list($icao, $data) = each($stations)) { + $str = str_pad($icao . PW_FIELD_SEPERATOR . + implode(PW_FIELD_SEPERATOR, $data), + PW_LINE_LENGTH - 1) . "\n"; fputs($fp, $str); } fclose($fp); + } else { + return false; } return true; Index: pw_db_pgsql.php =================================================================== RCS file: /cvsroot/phpweather/phpweather/db/pw_db_pgsql.php,v retrieving revision 1.5 retrieving revision 1.6 diff -u -3 -r1.5 -r1.6 --- pw_db_pgsql.php 20 May 2002 16:04:36 -0000 1.5 +++ pw_db_pgsql.php 28 Aug 2002 10:05:55 -0000 1.6 @@ -175,8 +175,8 @@ /** * Fetches a row as an associative array from the database. * - * @return array The next row from the result-set, as an associative - * array. + * @return array The next row from the result-set, as an + * associative array. * @access public */ function fetch_array() { @@ -279,30 +279,32 @@ $this->query('CREATE INDEX cc_key ON ' . $this->properties['db_stations'] . '(cc)'); - return true; // Succes! + return true; // Success! } + /** - * Translates an ICAO into a station name - * - * The boring ICAO (e.g. EKYT) is translated into something like - * 'Aalborg, Denmark'. + * Fetches information about an ICAO. * * @param string The ICAO one want's to translate. - * @return string The full name of the station, including country. + * @return array If the ICAO was found, then the array will + * contain three entries: the name of the station, + * the name of the country, the country code of the + * country. If the ICAO wasn't found, then false is + * returned. * @access public */ function lookup_icao($icao) { - $this->query('SELECT name, country FROM ' . - $this->properties['db_stations'] . " WHERE icao = '$icao'"); + $this->query(sprintf("SELECT name, country, cc FROM %s WHERE icao = '%s'", + $this->properties['db_stations'], addslashes($icao))); if ($this->num_rows() == 1) { - $row = $this->fetch_row(); - return "$row[0], $row[1]"; + return $this->fetch_row(); } else { - return $icao; + return false; } } + /** * Inserts the stations into the database. * @@ -358,7 +360,7 @@ } return $rows; } - + /** * Returns an array of stations. @@ -375,7 +377,7 @@ if (!$this->connect()) { return false; } - + $this->query('SELECT icao, name, country FROM ' . $this->properties['db_stations'] . " WHERE cc = '$cc' ORDER BY name"); |