<?php /** * Project: ePrintstats * File: inc.class.mysql.es.php * Description: All SQL interactions via this object. * This includes connections, adding, updating, inserting. */ class sqlconn { var $_mysql_error = array(); var $_database; var $_host_info; var $_debug = FALSE; var $_debugAll = array(); function doConnectServer($sqlserver,$sqluser,$sqlpass) { $connect = mysql_pconnect ($sqlserver,$sqluser,$sqlpass) or sqlconn::_setError(mysql_errno(),mysql_error()); $db_list = mysql_list_dbs($connect); while ($row = mysql_fetch_object($db_list)) { $this->_db_list[] = $row->Database; } $this->_host_info = sprintf ("MySQL host info: %s\n", mysql_get_host_info()); return $connect; } function doConnectDb($sqldatabase) { $db = mysql_select_db($sqldatabase) or sqlconn::_setError(mysql_errno(),mysql_error()); sqlconn::_setError(mysql_errno(),mysql_error()); $this->_database = $sqldatabase; return $db; } function closeConnection() { mysql_close(); } function getHostInfo() { return $this->_host_info; } function setDebug($debuglevel) { $this->_debug = $debuglevel; } function getDebug() { $_outstring = ''; foreach ($this->_debugAll as $k=>$v) { $_outstring .= $v; } return $_outstring; } function getError() { return $this->_mysql_error; } /* * @return void * @param $input unknown * @desc HTML output debug info * @usage sqlconn::_debug($this->_db_schema); */ function _debug($output,$line,$file,$function,$class) { ob_start(); print "<div class=\"debug\">\n"; print "<pre>\n"; if (!empty($line)) { print "LINE: $line\n"; }; if (!empty($file)) { print "FILE: $file\n"; }; if (!empty($function)) { print "FUNCTION: $function\n"; }; if (!empty($class)) { print "CLASS: $class\n"; }; //if (!empty($method)) { print "METHOD: $method\n"; }; // Only > PHP5 print_r($output); print "</ pre></div>"; $ret_str = ob_get_contents(); ob_end_clean(); $this->_debugAll[] = $ret_str; } function _setError($mysql_errno,$mysql_error) { /* * May be of limited use where a method makes multiple calls * and one error message is replaced by another. */ $this->_mysql_error["code"] = $mysql_errno; $this->_mysql_error["text"] = $mysql_error; } /******************************************** * * * Program specific * **********************************************/ /* ------------------------------------------------------------------------------ This function is a rewritten version of getCumulativeUsage, to optionally select the view_type. (c) Copyright 2004 Arthur Sale, University of Tasmania Parameters: id # of eprint strings 'abstract', 'download' or anything else acts as view=abstract+download Returns: Result array from query or failure ------------------------------------------------------------------------------ */ function getCumulativeUsageType($archive,$id,$type) { // NJS 2006-06-14: Added archive name as argument. // Build up the components of the WHERE clause (refactored). $where_parts = array(); $limit = ''; // Formulate the archive name part of the select. $this->addArchiveNameCondition( $archive, $where_parts ); // Formulate the id part of the select. $this->addArchiveIDCondition( $id, $where_parts ); // Formulate the view part of the select. $this->addViewTypeCondition( $type, $where_parts ); $limit = $this->buildWhereClause( $where_parts, 'AND' ); // Create a result array $records = array(); //Build up the query // NJS 2006-01-18: Added count of country_code. $query = " SELECT COUNT(*) AS count, COUNT(DISTINCT country_code) AS countries, MONTH(request_date) AS monthnum, DATE_FORMAT(request_date, '%b') AS month, YEAR(request_date) AS year FROM view $limit GROUP BY YEAR(request_date), MONTH(request_date) ORDER BY request_date DESC "; // Make the query $result = mysql_query($query); if (!$result) { sqlconn::_setError(mysql_errno(),mysql_error()); return mysql_error(); } else { while ($row = mysql_fetch_assoc($result)) { $records[] = $row; } return $records; } } /* ------------------------------------------------------------------------------ This function is a rewritten version of getCumulativeUsageCountry, to optionally select the view_type. (c) Copyright 2004 Arthur Sale, University of Tasmania Parameters: id # of eprint strings 'abstract', 'download' or anything else acts as view=abstract+download Returns: Result array from query or failure ------------------------------------------------------------------------------ */ function getCumulativeUsageCountryType($archive,$type) { // NJS 2006-06-14: Added archive name as argument. // Build up the components of the WHERE clause (refactored). $where_parts = array(); $limit = ''; // Formulate the archive name part of the select. $this->addArchiveNameCondition( $archive, $where_parts ); // Formulate the view part of the select. $this->addViewTypeCondition( $type, $where_parts ); $limit = $this->buildWhereClause( $where_parts, 'AND' ); // Create a result array $records = array(); //Build up the query // NJS 2006-05-02: Fixed typo in ORDER BY and added ascending order of country // name for countries with the same number of accesses. $query = " SELECT COUNT(*) AS count, country_name, country_code FROM view $limit GROUP BY country_name ORDER BY count DESC, country_name ASC "; $result = mysql_query($query); if (!$result) { sqlconn::_setError(mysql_errno(),mysql_error()); return mysql_error(); } else { while ($row = mysql_fetch_assoc($result)) { $records[] = $row; } return $records; } } /* ------------------------------------------------------------------------------ */ function getArchiveCountDate($archive,$year,$month,$range,$type='download') { // NJS 2006-06-14: Added archive name as argument. $year = (int) $year; $month = (int) $month; $records = array(); // Build up the components of the WHERE clause (refactored). $where_parts = array(); $limit = ''; // Formulate the archive name part of the select. $this->addArchiveNameCondition( $archive, $where_parts ); // create a date based limit $this->addYearCondition( $year, $where_parts ); $this->addMonthCondition( $month, $where_parts ); // Note that year(+month) is mutually exclusive of "4w" (last four // weeks), but we don't check for this. (The original code didn't // check either.) $this->addFourWeeksCondition( $range, $where_parts ); // Constrain the view to downloads - Arthur Sale addition ----------- $this->addViewTypeCondition( 'download', $where_parts ); // End of addition -------------------------------------------------- $limit = $this->buildWhereClause( $where_parts, 'AND' ); // NJS 2006-01-18: Added count of country_code. // NJS 2006-05-02: Added descending order of number of countries and // ascending order of title for eprints with the same number of // downloads. $query = " SELECT COUNT(*) AS count, COUNT(DISTINCT country_code) AS countries, archiveid, archive_name, eprint_name FROM view $limit GROUP BY archiveid, archive_name ORDER BY count DESC, countries DESC, eprint_name ASC "; $result = mysql_query($query); if (!$result) { sqlconn::_setError(mysql_errno(),mysql_error()); return mysql_error(); } else { while ($row = mysql_fetch_assoc($result)) { $records[] = $row; } return $records; } } /* NJS 2005-12-15 getArchiveCountCountry() arguments: $archive archive name $ccode country code $type eprint view type (e.g., download) returns: array Similar to getArchiveCountDate but does it by country code instead of by date. */ function getArchiveCountCountry($archive,$ccode,$type='download') { // NJS 2006-06-14: Added archive name as argument. $records = array(); // Build up the components of the WHERE clause (refactored). $where_parts = array(); $limit = ''; // Create a country based limit. Also constrain to downloads only // in the appropriate archive. $this->addArchiveNameCondition( $archive, $where_parts ); $this->addStringCondition( 'country_code', '=', $ccode, $where_parts ); $this->addViewTypeCondition( 'download', $where_parts ); $limit = $this->buildWhereClause( $where_parts, 'AND' ); // NJS 2003-05-02: Added ascending order of title for eprints with // the same number of downloads. $query = " SELECT COUNT(*) AS count, archiveid, archive_name, eprint_name, country_name FROM view $limit GROUP BY archiveid, archive_name ORDER BY count DESC, eprint_name ASC "; $result = mysql_query($query); if (!$result) { sqlconn::_setError(mysql_errno(),mysql_error()); return mysql_error(); } else { while ($row = mysql_fetch_assoc($result)) { $records[] = $row; } return $records; } } /* New */ function getCountryEprintType($archive,$year,$month,$rnge,$type,$id) { // NJS 2006-06-14: Added archive name as argument. $year = (int) $year; $month = (int) $month; $records = array(); // Build up the components of the WHERE clause (refactored). $where_parts = array(); $limit = ''; $this->addArchiveNameCondition( $archive, $where_parts ); $this->addArchiveIDCondition( $id, $where_parts ); // Generate type enquiry $this->addViewTypeCondition( 'download', $where_parts ); // generate date enquiry $this->addYearCondition( $year, $where_parts ); $this->addMonthCondition( $month, $where_parts ); // Note that year(+month) is mutually exclusive of "4w" (last four // weeks), but we don't check for this. (The original code didn't // check either.) $this->addFourWeeksCondition( $rnge, $where_parts ); $limit = $this->buildWhereClause( $where_parts, 'AND' ); // NJS 2006-05-02: Added ascending order of country // name for countries with the same number of accesses. $query = " SELECT COUNT(*) AS count, country_name, country_code FROM view $limit GROUP BY country_name ORDER BY count DESC, country_name ASC "; $result = mysql_query($query); if (!$result) { sqlconn::_setError(mysql_errno(),mysql_error()); return mysql_error(); } else { while ($row = mysql_fetch_assoc($result)) { $records[] = $row; } return $records; } } function getTitle($archive,$id) { // Get the title of an eprint given its id // NJS 2006-06-14: Added archive name as argument. // Build up the components of the WHERE clause (refactored). $where_parts = array(); $limit = ''; $this->addArchiveNameCondition( $archive, $where_parts ); $this->addArchiveIDCondition( $id, $where_parts ); $limit = $this->buildWhereClause( $where_parts, 'AND' ); $query = " SELECT eprint_name FROM view $limit "; $result = mysql_query($query); if (!$result) { sqlconn::_setError(mysql_errno(),mysql_error()); return; } else { $row = mysql_fetch_assoc($result); return $row["eprint_name"]; } } function getAbstractDownload($archive,$year,$month,$range,$type='download',$id) { // NJS 2006-06-14: Added archive name as argument. $year = (int) $year; $month = (int) $month; $records = array(); // Build up the components of the WHERE clause (refactored). $where_parts = array(); $limit = ''; $this->addArchiveNameCondition( $archive, $where_parts ); $this->addArchiveIDCondition( $id, $where_parts ); $this->addYearCondition( $year, $where_parts ); $this->addMonthCondition( $month, $where_parts ); // Note that year(+month) is mutually exclusive of "4w" (last four // weeks), but we don't check for this. (The original code didn't // check either.) $this->addFourWeeksCondition( $range, $where_parts ); $limit = $this->buildWhereClause( $where_parts, 'AND' ); // NJS 2006-01-18: Added count of country_code. // NJS 2006-05-02: Added ascending order of country code. $query = " SELECT COUNT(*) AS count, COUNT(DISTINCT country_code) AS countries, view_type FROM view $limit GROUP BY view_type ORDER BY count DESC, country_code ASC "; $result = mysql_query($query); if (!$result) { sqlconn::_setError(mysql_errno(),mysql_error()); return mysql_error(); } else { while ($row = mysql_fetch_assoc($result)) { $records[] = $row; } return $records; } } function getLastProc() { // Get the time that the stats were last processed. // Note that the archive name is irrelevant for this, // as the stats are updated for ALL archives at the // same time. $query = " SELECT timeinsert FROM lastproc ORDER BY id DESC LIMIT 1 "; $result = mysql_query($query); if (!$result) { sqlconn::_setError(mysql_errno(),mysql_error()); return; } else { $row = mysql_fetch_assoc($result); return $row["timeinsert"]; } } /* NJS 2006-02-09 (moved here from inc.fns.show_detail_eprint.es.php) Grab the title of an eprint from the repository. Only needed if the title isn't already in the stats database, which should only occur when an eprint hasn't been downloaded yet. Do nothing if the archive name is empty or "default". We could be more clever about this and raise some kind of error if the eprint ID doesn't exist in the archive, but I don't see that it would add that much to the overall user experience :) */ function getEPrintTitle($archive,$eprint_id) { // NJS 2006-06-14: Added archive name as argument to support // multi-archive statistics. $eprint_title = ''; if ( ( $archive != '' ) and ( $archive != 'default' ) ) { $conn_eprints = mysql_connect( $GLOBALS["config_vars"]["connections"]["eprints_archives"][$archive]["sqlserver_eprints"], $GLOBALS["config_vars"]["connections"]["eprints_archives"][$archive]["sqluser_eprints"], $GLOBALS["config_vars"]["connections"]["eprints_archives"][$archive]["sqlpass_eprints"] ); $db_eprints = mysql_select_db( $archive, $conn_eprints ); if (!$db_eprints) return $eprint_title; $query_eprints = " SELECT title FROM archive WHERE eprintid = $eprint_id "; $result_eprints = mysql_query($query_eprints,$conn_eprints); $row_eprints = mysql_fetch_assoc($result_eprints); $eprint_title = trim($row_eprints["title"]); $eprint_title = preg_replace("/\s+/"," ",$eprint_title); mysql_close($conn_eprints); } return $eprint_title; } /* NJS 2006-06-14 buildWhereClause() arguments: $where_parts array of WHERE clause conditions $op boolean operator to separate conditions with (e.g., 'AND') returns: string Given an array of condition strings, build a WHERE clause, combining the conditions using the specified operator. (If you need to build something more complex, you'll have to do it manually.) */ function buildWhereClause( $where_parts, $op ) { $limit = ''; $num_parts = count( $where_parts ); if ( $num_parts > 0 ) { $limit = 'WHERE '; // Append all but the last one, with the specified operator. for ( $i = 0; $i < ( $num_parts - 1 ); $i++ ) { $limit .= $where_parts[$i] . " $op "; } // Append the last one with no operator. $limit .= $where_parts[$num_parts - 1]; } return $limit; } /* NJS 2006-06-14 addArchiveNameCondition() arguments: $archive the name of an archive $where_parts reference to an array to which to add the new condition string returns: void Add a condition for the archive name to the list of WHERE conditions. Do nothing if the archive name is empty. We also ignore the value "default" in order to be backwards-compatible with earlier versions of the stats package. Note that in either of the latter two cases this means that ALL stats for ALL archives will be queried! */ function addArchiveNameCondition ( $archive, &$where_parts ) { if ( ( $archive != '' ) and ( $archive != 'default' ) ) $this->addStringCondition( 'archive_name', '=', $archive, $where_parts ); } /* NJS 2006-06-14 addArchiveIDCondition() arguments: $id the id of an eprint $where_parts reference to an array to which to add the new condition string returns: void Add a condition for the eprint ID to the list of WHERE conditions. Do nothing if the eprint ID is zero or less. */ function addArchiveIDCondition ( $id, &$where_parts ) { $id = (int) $id; // BUG FIX: ID should be > 0, not > 1! if ( $id > 0 ) $this->addNumericCondition( 'archiveid', '=', $id, $where_parts ); } /* NJS 2006-06-14 addViewTypeCondition() arguments: $type the type of archive view (download or abstract) $where_parts reference to an array to which to add the new condition string returns: void Add a condition for the eprint view type to the list of WHERE conditions. Do nothing if the view type is not "download" or "abstract". */ function addViewTypeCondition ( $type, &$where_parts ) { if ( ( $type == 'download' ) or ( $type == 'abstract' ) ) $this->addStringCondition( 'view_type', '=', $type, $where_parts ); } /* NJS 2006-06-14 addYearCondition() arguments: $year the year to filter on $where_parts reference to an array to which to add the new condition string returns: void Add a condition for the year to the list of WHERE conditions. Do nothing if the year is outside the range 1990--2100. (Note: lower bound changed from 2002 as it seems more appropriate.) NJS 2006-01-18: Fixed upper year bound (was 2005). */ function addYearCondition ( $year, &$where_parts ) { if ( ( $year >= 1990 ) and ( $year < 2100 ) ) $this->addStringCondition( 'YEAR(request_date)', '=', $year, $where_parts ); } /* NJS 2006-06-14 addMonthCondition() arguments: $month the month to filter on $where_parts reference to an array to which to add the new condition string returns: void Add a condition for the month to the list of WHERE conditions. Do nothing if the month is outside the range 1--12. */ function addMonthCondition ( $month, &$where_parts ) { if ( ( $month > 0 ) and ( $month <= 12 ) ) $this->addStringCondition( 'MONTH(request_date)', '=', $month, $where_parts ); } /* NJS 2006-06-14 addFourWeeksCondition() arguments: $range the range to filter on $where_parts reference to an array to which to add the new condition string returns: void Add a condition for the last four weeks to the list of WHERE conditions. Do nothing if the range is not "4w". */ function addFourWeeksCondition ( $range, &$where_parts ) { if ( $range == '4w' ) $this->addExprCondition( 'request_date', '>=', 'DATE_SUB(CURDATE(),INTERVAL 1 MONTH)', $where_parts ); } /* NJS 2006-06-14 addStringCondition() arguments: $column the name of the SQL column $op the comparison operator $value the value to be tested $where_parts reference to an array to which to add the new condition string returns: void Add a generic condition for a string column to the list of WHERE conditions. Any validation of the value should be done prior to calling this function. */ function addStringCondition ( $column, $op, $value, &$where_parts ) { $where_parts[] = "$column $op '$value'"; } /* NJS 2006-06-14 addNumericCondition() arguments: $column the name of the SQL column $op the comparison operator $value the value to be tested $where_parts reference to an array to which to add the new condition string returns: void Add a generic condition for a numeric column to the list of WHERE conditions. Any validation of the value should be done prior to calling this function. */ function addNumericCondition ( $column, $op, $value, &$where_parts ) { $where_parts[] = "$column $op $value"; } /* NJS 2006-06-16 addExprCondition() arguments: $column the name of the SQL column $op the comparison operator $expr the expression to be tested $where_parts reference to an array to which to add the new condition string returns: void Add to the list of WHERE conditions a generic condition for a column to be tested against some arbitrary expression. Any validation of the value should be done prior to calling this function. */ function addExprCondition ( $column, $op, $expr, &$where_parts ) { $where_parts[] = "$column $op $expr"; } } ?>