File:  [Paefchen] / FreeBSD / tinderbox / webui / core / TinderboxDS.php
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Fri Nov 2 20:56:34 2007 UTC (17 years ago) by as
Branches: MAIN
CVS tags: ORIG_3_0, HEAD, CH2PHP5
import 3.0

<?php
#-
# Copyright (c) 2004-2005 FreeBSD GNOME Team <freebsd-gnome@FreeBSD.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $MCom: portstools/tinderbox/webui/core/TinderboxDS.php,v 1.36 2007/10/13 02:28:47 ade Exp $
#

    require_once 'DB.php';
    require_once 'Build.php';
    require_once 'BuildPortsQueue.php';
    require_once 'Config.php';
    require_once 'Jail.php';
    require_once 'Port.php';
    require_once 'PortsTree.php';
    require_once 'PortFailReason.php';
    require_once 'User.php';
    require_once 'inc_ds.php';
    require_once 'inc_tinderbox.php';

    $objectMap = array(
        "Build" => "builds",
	"BuildPortsQueue" => "build_ports_queue",
        "Config" => "config",
        "Jail"  => "jails",
        "Port"  => "ports",
        "PortsTree" => "ports_trees",
        "PortFailReason" => "port_fail_reasons",
        "User"  => "users",
    );

    class TinderboxDS {
        var $db;
        var $error;
        var $packageSuffixCache; /* in use by getPackageSuffix() */

        function TinderboxDS() {
            global $DB_HOST, $DB_DRIVER, $DB_NAME, $DB_USER, $DB_PASS;

            # XXX: backwards compatibility
            if ($DB_DRIVER == "")
                $DB_DRIVER = "mysql";

            $dsn = "$DB_DRIVER://$DB_USER:$DB_PASS@$DB_HOST/$DB_NAME";

            $this->db = DB::connect($dsn);

            if (DB::isError($this->db)) {
                die ("Tinderbox DS: Unable to initialize datastore: " . $this->db->getMessage() . "\n");
            }

            $this->db->setFetchMode(DB_FETCHMODE_ASSOC);
            $this->db->setOption('persistent', true);
        }

        function start_transaction() {
                $this->db->autoCommit( false );
        }

        function commit_transaction() {
                $this->db->commit();
                $this->db->autoCommit( true );
        }

        function rollback_transaction() {
                $this->db->rollback();
                $this->db->autoCommit( true );
        }

        function getAllMaintainers() {
            $query = "SELECT DISTINCT LOWER(port_maintainer) AS port_maintainer FROM ports where port_maintainer IS NOT NULL ORDER BY LOWER(port_maintainer)";
            $rc = $this->_doQueryHashRef($query, $results, array());

            if (!$rc) {
                return array();
            }

            foreach($results as $result)
                $data[]=$result['port_maintainer'];

            return $data;
        }

        function getAllPortsByPortID($portid) {
            $query = "SELECT p.*,
                             bp.build_id,
                             bp.last_built,
                             bp.last_status,
                             bp.last_successful_built,
			     bp.last_failed_dependency,
			     bp.last_run_duration,
                             bp.last_built_version,
                        CASE bp.last_fail_reason
                           WHEN '__nofail__' THEN ''
                           ELSE bp.last_fail_reason
                        END
		          AS last_fail_reason
                        FROM ports p,
                             build_ports bp
                       WHERE p.port_id = bp.port_id
                         AND bp.port_id=$portid";

            $rc = $this->_doQueryHashRef($query, $results, array());

            if (!$rc) {
                return null;
            }

            $ports = $this->_newFromArray("Port", $results);

            return $ports;
        }


        function addUser($user) {
            $query = "INSERT INTO users
                         (user_name,user_email,user_password,user_www_enabled)
                      VALUES
                         (?,?,?,?)";

            $rc = $this->_doQuery($query, array($user->getName(),$user->getEmail(),$user->getPassword(),$user->getWwwEnabled()),$res);

            if (!$rc) {
                return false;
            }

            return true;
        }

        function deleteUser($user) {
            if( !$user->getId() || $this->deleteUserPermissions($user,'') ) {
		if ($user->getId()) {
			$this->deleteBuildPortsQueueByUserId($user);
		}
                $query = "DELETE FROM users
                                WHERE user_name=?";

                $rc = $this->_doQuery($query, array($user->getName()),$res);

                if (!$rc) {
                     return false;
                }

                return true;
            }
            return false;
        }

        function updateUser($user) {
            $query = "UPDATE users
                         SET user_name=?,user_email=?,user_password=?,user_www_enabled=?
                       WHERE user_id=?";

            $rc = $this->_doQuery($query, array($user->getName(),$user->getEmail(),$user->getPassword(),$user->getWwwEnabled(),$user->getId()),$res);

            if (!$rc) {
                return false;
            }

            return true;
        }

        function getUserByLogin($username,$password) {
            $hashPass = md5($password);
            $query = "SELECT user_id,user_name,user_email,user_password,user_www_enabled FROM users WHERE user_name=? AND user_password=?";
            $rc = $this->_doQueryHashRef($query, $results, array($username,$hashPass));

            if (!$rc) {
                return null;
            }

            $user = $this->_newFromArray("User", $results);

            return $user[0];
        }

        function getUserPermissions($user_id,$object_type,$object_id) {

            $query = "
                SELECT
                CASE user_permission
                   WHEN 1 THEN 'IS_WWW_ADMIN'
		   WHEN 2 THEN 'PERM_ADD_QUEUE'
		   WHEN 3 THEN 'PERM_MODIFY_OWN_QUEUE'
		   WHEN 4 THEN 'PERM_DELETE_OWN_QUEUE'
		   WHEN 5 THEN 'PERM_PRIO_LOWER_5'
		   WHEN 6 THEN 'PERM_MODIFY_OTHER_QUEUE'
		   WHEN 7 THEN 'PERM_DELETE_OTHER_QUEUE'
                   ELSE 'PERM_UNKNOWN'
                END
                   AS user_permission
                 FROM user_permissions
                WHERE user_id=?
                  AND user_permission_object_type=?
                  AND user_permission_object_id=?";

            $rc = $this->_doQueryHashRef($query, $results, array($user_id,$object_type,$object_id));

            if (!$rc) {
                return null;
            }

            return $results;
        }

        function deleteUserPermissions($user, $object_type) {

            $query = "
                DELETE FROM user_permissions
                      WHERE user_id=?";

            if( $object_type )
                $query .= " AND user_permission_object_type='$object_type'";

            $rc = $this->_doQuery($query, array($user->getId()), $res);

            if (!$rc) {
                return false;
            }

            return true;
        }

        function addUserPermission($user_id,$object_type,$object_id,$permission) {

            switch( $permission ) {
//              case 'IS_WWW_ADMIN':             $permission = 1; break;   /* only configureable via shell */
		case 'PERM_ADD_QUEUE':		 $permission = 2; break; 
		case 'PERM_MODIFY_OWN_QUEUE':	 $permission = 3; break;
		case 'PERM_DELETE_OWN_QUEUE':	 $permission = 4; break;
		case 'PERM_PRIO_LOWER_5':	 $permission = 5; break;
		case 'PERM_MODIFY_OTHER_QUEUE':	 $permission = 6; break;
		case 'PERM_DELETE_OTHER_QUEUE':	 $permission = 7; break;
                default:                         return false;
            }

            $query = "
                INSERT INTO user_permissions
                    (user_id,user_permission_object_type,user_permission_object_id,user_permission)
                   VALUES
                    (?,?,?,?)";

            $rc = $this->_doQuery($query, array($user_id,$object_type,$object_id,$permission), $res);

            if (!$rc) {
                return false;
            }

            return true;
        }

        function getBuildPortsQueueEntries($build_id) {
            $query = "SELECT build_ports_queue.*, builds.build_name AS build_name, users.user_name AS user_name
                        FROM build_ports_queue, builds, users
                       WHERE build_ports_queue.build_id=?
                         AND builds.build_id = build_ports_queue.build_id
                         AND users.user_id = build_ports_queue.user_id
                    ORDER BY priority ASC, build_ports_queue_id ASC";
            $rc = $this->_doQueryHashRef($query, $results, array($build_id));

            if (!$rc) {
                return null;
            }

            $build_ports_queue_entries = $this->_newFromArray("BuildPortsQueue", $results);

            return $build_ports_queue_entries;
        }

        function deleteBuildPortsQueueEntry($entry_id) {
            $query = "DELETE FROM build_ports_queue
                            WHERE build_ports_queue_id=?";

            $rc = $this->_doQuery($query, $entry_id, $res);

            if (!$rc) {
                return false;
            }

            return true;
        }

        function deleteBuildPortsQueueByUserId($user) {
            $query = "DELETE FROM build_ports_queue
                            WHERE user_id=?";

            $rc = $this->_doQuery($query, $user->getId(), $res);

            if (!$rc) {
                return false;
            }

            return true;
        }

        function createBuildPortsQueueEntry($build_id,$priority,$port_directory,$user_id,$email_on_completion) {
            switch( $email_on_completion ) {
                case '1':    $email_on_completion = 1; break;
                default:     $email_on_completion = 0; break;
            }

            $entries[] = array('build_id'       => $build_id,
                               'priority'       => $priority,
                               'port_directory' => $port_directory,
                               'user_id'        => $user_id,
                               'enqueue_date'   => date("Y-m-d H:i:s", time()),
                               'email_on_completion' => $email_on_completion,
                               'status'         => 'ENQUEUED');

            $results = $this->_newFromArray("BuildPortsQueue",$entries);

            return $results[0];
        }

        function updateBuildPortsQueueEntry($entry) {

            $query = "UPDATE build_ports_queue
                         SET build_id=?, priority=?, email_on_completion=?, status=?
                       WHERE build_ports_queue_id=?";

            $rc = $this->_doQuery($query, array($entry->getBuildId(),$entry->getPriority(),$entry->getEmailOnCompletion(),$entry->getStatus(),$entry->getId()), $res);

            if (!$rc) {
                return false;
            }

            return true;
        }

        function addBuildPortsQueueEntry($entry) {
            $query = "INSERT INTO build_ports_queue
                         (enqueue_date,build_id,priority,port_directory,user_id,email_on_completion,status)
                      VALUES
                         (?,?,?,?,?,?,?)";

            $rc = $this->_doQuery($query, array($entry->getEnqueueDate(),$entry->getBuildId(),$entry->getPriority(),$entry->getPortDirectory(),$entry->getUserId(),$entry->getEmailOnCompletion(),$entry->getStatus()), $res);

            if (!$rc) {
                return false;
            }

            return true;
        }

        function getBuildPortsQueueEntryById($id) {
            $results = $this->getBuildPortsQueue(array( 'build_ports_queue_id' => $id ));

            if (is_null($results)) {
                 return null;
            }

            return $results[0];
        }

        function getPortsForBuild($build, $sortby = 'port_directory') {
	    $sortbytable = "bp";
	    if ($sortby == "") $sortby = "port_directory";
	    if ($sortby == "port_directory") $sortbytable = "p";
	    if ($sortby == "port_maintainer") $sortbytable = "p";
            $query = "SELECT p.*,
                             bp.last_built,
                             bp.last_status,
                             bp.last_successful_built,
                             bp.last_built_version,
			     bp.last_failed_dependency,
			     bp.last_run_duration,
                        CASE bp.last_fail_reason
                           WHEN '__nofail__' THEN ''
                           ELSE bp.last_fail_reason
                        END
		          AS last_fail_reason
                        FROM ports p,
                             build_ports bp
                       WHERE p.port_id = bp.port_id
                         AND bp.build_id=?
                    ORDER BY $sortbytable.$sortby";

            $rc = $this->_doQueryHashRef($query, $results, $build->getId());

            if (!$rc) {
                return null;
            }

            $ports = $this->_newFromArray("Port", $results);

            return $ports;
        }

        function getLatestPorts($build_id,$limit="") {
            $query = "SELECT p.*,
                             bp.build_id,
                             bp.last_built,
                             bp.last_status,
                             bp.last_successful_built,
                             bp.last_built_version,
			     bp.last_failed_dependency,
			     bp.last_run_duration,
                        CASE bp.last_fail_reason
                           WHEN '__nofail__' THEN ''
                           ELSE bp.last_fail_reason
                        END
		          AS last_fail_reason
                        FROM ports p,
                             build_ports bp
                       WHERE p.port_id = bp.port_id
                         AND bp.last_built IS NOT NULL ";
            if($build_id)
                 $query .= "AND bp.build_id=$build_id ";
            $query .= " ORDER BY bp.last_built DESC ";
            if($limit)
                 $query .= " LIMIT $limit";

            $rc = $this->_doQueryHashRef($query, $results, array());

            if (!$rc) {
                return null;
            }

            $ports = $this->_newFromArray("Port", $results);

            return $ports;
        }

	function getBuildPorts($port_id,$build_id) {
		$query = "SELECT p.*,
			         bp.last_built,
				 bp.last_status,
				 bp.last_successful_built,
				 bp.last_failed_dependency,
				 bp.last_run_duration,
			 CASE bp.last_fail_reason
			    WHEN '__nofail__' THEN ''
			    ELSE bp.last_fail_reason
			 END
			  AS last_fail_reason
			 FROM ports p,
			      build_ports bp
			 WHERE p.port_id = bp.port_id
			 AND bp.build_id=?
			 AND bp.port_id=?";

		$rc = $this->_doQueryHashRef($query, $results, array($build_id, $port_id));
		if (!$rc) return null;

		$ports = $this->_newFromArray("Port", $results);

		return $ports[0];
	}


        function getPortsByStatus($build_id,$maintainer,$status,$notstatus) {
            $query = "SELECT p.*,
                             bp.build_id,
                             bp.last_built,
                             bp.last_status,
                             bp.last_successful_built,
                             bp.last_built_version,
			     bp.last_failed_dependency,
			     bp.last_run_duration,
                        CASE bp.last_fail_reason
                           WHEN '__nofail__' THEN ''
                           ELSE bp.last_fail_reason
                        END
		          AS last_fail_reason
                        FROM ports p,
                             build_ports bp
                       WHERE p.port_id = bp.port_id ";

            if($build_id)
                 $query .= "AND bp.build_id=$build_id ";
            if($status<>'')
                 $query .= "AND bp.last_status='$status' ";
	    if($notstatus<>'')
		 $query .= "AND bp.last_status<>'$notstatus' AND bp.last_status<>'UNKNOWN'";
            if($maintainer)
                 $query .= "AND p.port_maintainer='$maintainer'";
            $query .= " ORDER BY bp.last_built DESC ";

            $rc = $this->_doQueryHashRef($query, $results, array());

            if (!$rc) {
                return null;
            }

            $ports = $this->_newFromArray("Port", $results);

            return $ports;
        }

	function getBuildStatsWithStatus($build_id) {
	    $query = 'SELECT last_status,COUNT(*) AS c FROM build_ports WHERE build_id = ? GROUP BY last_status';
	    $rc = $this->_doQueryHashRef($query, $results, $build_id);
	    if (!$rc) return null;
	    return $results;
	}


        function getBuildStats($build_id) {
            $query = 'SELECT COUNT(*) AS fails FROM build_ports WHERE last_status = \'FAIL\' AND build_id = ?';
            $rc = $this->_doQueryHashRef($query, $results, $build_id);
            if (!$rc) return null;
            return $results[0];
        }

        function getPortById($id) {
            $results = $this->getPorts(array( 'port_id' => $id ));

            if (is_null($results)) {
                return null;
            }

            return $results[0];
        }

	function getPortByDirectory($dir) {
	    $results = $this->getPorts(array( 'port_directory' => $dir ));

	    if (is_null($results)) {
                return null;
	    }

	    return $results[0];
	}

	function getCurrentPortForBuild($build_id) {
	    $query = 'SELECT port_id AS id FROM build_ports WHERE build_id = ? AND currently_building = \'1\'';
	    $rc = $this->_doQueryHashRef($query, $results, array($build_id));
	    if (!$rc) return null;
	    $port = $this->getPortById($results[0]['id']);

	    return $port;
	}

        function getObjects($type, $params = array()) {
            global $objectMap;

            if (!isset($objectMap[$type])) {
                die("Unknown object type, $type\n");
            }

            $table = $objectMap[$type];
            $condition = "";

            $values = array();
            $conds = array();
            foreach ($params as $field => $param) {
                # Each parameter makes up and OR portion of a query.  Within
                # each parameter can be a hash reference that make up the AND
                # portion of the query.
                if (is_array($param)) {
                    $ands = array();
                    foreach ($param as $andcond => $value) {
                        array_push($ands, "$andcond=?");
                        array_push($values, $value);
                    }
                    array_push($conds, "(" . (implode(" AND ", $ands)) . ")");
                } else {
                    array_push($conds, "(" . $field . "=?)");
                    array_push($values, $param);
                }
            }

            $condition = implode(" OR ", $conds);

            if ($condition != "") {
                $query = "SELECT * FROM $table WHERE $condition";
            }
            else {
                $query = "SELECT * FROM $table";
            }

            $results = array();
            $rc = $this->_doQueryHashRef($query, $results, $values);

            if (!$rc) {
                return null;
            }

            return $this->_newFromArray($type, $results);
        }

        function getBuildByName($name) {
            $results = $this->getBuilds(array( 'build_name' => $name ));

            if (is_null($results)) {
                return null;
            }

            return $results[0];
        }

        function getBuildById($id) {
            $results = $this->getBuilds(array( 'build_id' => $id ));

            if (is_null($results)) {
                return null;
            }

            return $results[0];
        }

        function getJailById($id) {
            $results = $this->getJails(array( 'jail_id' => $id ));

            if (is_null($results)) {
                return null;
            }

            return $results[0];
        }

        function getPortsTreeForBuild($build) {
            $portstree = $this->getPortsTreeById($build->getPortsTreeId());

            return $portstree;
        }

        function getPortsTreeByName($name) {
             $results = $this->getPortsTrees(array( 'ports_tree_name' => $name ));
             if (is_null($results)) {
                 return null;
             }

             return $results[0];
        }

        function getPortsTreeById($id) {
            $results = $this->getPortsTrees(array( 'ports_tree_id' => $id ));

            if (is_null($results)) {
                 return null;
            }

            return $results[0];
        }

        function getUserById($id) {
            $results = $this->getUsers(array( 'user_id' => $id ));

            if (is_null($results)) {
                return null;
            }

            return $results[0];
        }

        function getUserByName($name) {
            $results = $this->getUsers(array( 'user_name' => $name ));

            if (is_null($results)) {
                return null;
            }

            return $results[0];
        }

        function getConfig($params = array()) {
            return $this->getObjects("Config", $params);
        }

	function getBuildPortsQueue($params = array()) {
	    return $this->getObjects("BuildPortsQueue", $params);
	}

        function getBuilds($params = array()) {
            return $this->getObjects("Build", $params);
        }

	function getPorts($params = array()) {
	    return $this->getObjects("Port", $params);
	}

        function getJails($params = array()) {
            return $this->getObjects("Jail", $params);
        }

        function getPortFailReasons($params = array()) {
            return $this->getObjects("PortFailReason", $params);
        }

        function getPortsTrees($params = array()) {
            return $this->getObjects("PortsTree", $params);
        }

        function getUsers($params = array()) {
            return $this->getObjects("User", $params);
        }

        function getAllConfig() {
            $config = $this->getConfig();

            return $config;
        }

        function getAllBuilds() {
            $builds = $this->getBuilds();

            return $builds;
        }

        function getAllJails() {
            $jails = $this->getJails();

            return $jails;
        }

        function getAllPortFailReasons() {
            $results = $this->getPortFailReasons();

            return $results;
        }

        function getAllPortsTrees() {
            $ports_trees = $this->getPortsTrees();

            return $ports_trees;
        }

        function getAllUsers() {
            $users = $this->getUsers();

            return $users;
        }

        function addError($error) {
             return $this->error[] = $error;
        }

        function getErrors() {
             return $this->error;
        }

        function _doQueryNumRows($query, $params = array()) {
            $rows = 0;
            $rc = $this->_doQuery($query, $params, $res);

            if (!$rc) {
                return -1;
            }

            if ($res->numRows() > -1) {
                $rows = $res->numRows();
            }
            else {
                while($res->fetchRow()) {
                    $rows++;
                }
            }

            $res->free();

            return $rows;
        }

        function _doQueryHashRef($query, &$results, $params = array()) {
            $rc = $this->_doQuery($query, $params, $res);

            if (!$rc) {
                $results = null;
                return 0;
            }

            $results = array();
            while ($row = $res->fetchRow()) {
                array_push($results, $row);
            }

            $res->free();

            return 1;
        }

        function _doQuery($query, $params, &$res) {
            $sth = $this->db->prepare($query);

            if (DB::isError($this->db)) {
                $this->addError($this->db->getMessage());
                return 0;
            }

            if (count($params)) {
                $_res = $this->db->execute($sth, $params);
            }
            else {
                $_res = $this->db->execute($sth);
            }

            if (DB::isError($_res)) {
                $this->addError($_res->getMessage());
                return 0;
            }

            if (!is_null($_res)) {
                $res = $_res;
            }
            else {
                $res->free();
            }

            return 1;
        }

        function _newFromArray($type, $arr) {
            $objects = array();

            foreach ($arr as $item) {
                eval('$obj = new $type($item);');
                if (!is_a($obj, $type)) {
                    return null;
                }
                array_push($objects, $obj);
            }

            return $objects;
        }

        function destroy() {
            $this->db->disconnect();
            $this->error = null;
        }

        function getPackageSuffix($jail_id) {
            if (empty($jail_id)) return "";
            /* Use caching to avoid a lot of SQL queries */
            if ( isset($this->packageSuffixCache[$jail_id])) {
                return $this->packageSuffixCache[$jail_id];
            } else {
                $jail = $this->getJailById($jail_id);
                if (substr($jail->getName(), 0, 1) <= "4") {
                        $this->packageSuffixCache[$jail_id] = ".tgz";
                        return ".tgz";
                } else {
                        $this->packageSuffixCache[$jail_id] = ".tbz";
                        return ".tbz";
                }

            }
        }
   }
?>