<?php
/*-
 * Copyright (c) 2008 Fredrik Lindberg - http://www.shapeshifter.se
 * 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 ``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 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.
 *
 */

require_once('db/iface.inc');
require_once(
'prefs.inc');

class 
jobs {
    private 
$m_con;
    const 
jobversion '1';
    private 
$m_data = array(
        
'version' => self::jobversion,
        
'include' => array(),
        
'callback' => '',
        
'args' => null,
    );

    private 
$m_prefs;

    public function 
__construct($connector) {
        
$this->m_con $connector;
        
$this->m_prefs = new Prefs($connector'jobs');
    }

    public function 
enqueue($cb$args$incs) {
        
$data $this->m_data;
        
$data['include'] = $incs;
        
$data['callback'] = $cb;
        
$data['args'] = $args;

        
$str addslashes(serialize($data));

        
$this->m_con->query("insert into jobs (jid, data) values (NULL, \"$str\")");
        
$this->startWorker();
    }

    public function 
nextJob()
    {
        
$this->m_con->query('select count(*) as job_count from jobs');
        
$res $this->m_con->fetchRow();
        if (
$res[0] == 0)
            return -
1;

        
$this->m_con->query('select jid, data from jobs limit 1');
        
$res $this->m_con->fetchRow();
        
$jid $res[0];
        return 
$jid;
    }

    public function 
dequeue($jid)
    {
        
$tmp addslashes($jid);
        
$this->m_con->query("select data from jobs where jid = $tmp");
        
$res $this->m_con->fetchRow();
        
$data unserialize(stripslashes($res[0]));
        
$this->m_con->query("delete from jobs where jid = $tmp");

        if (
$data['version'] != self::jobversion)
            return 
null;

        return array(
'jid' => $jid,
            
'include' => $data['include'],
            
'callback' => $data['callback'],
            
'args' => $data['args']);
    }

    private function 
startWorker()
    {
        
$prefs = new Prefs($this->m_con'jobs');
        
$pid $prefs->worker_pid;
        if (
$pid != null)
            return;

        
$cwd getcwd();
        
$cmd escapeshellcmd(PHP_PATH ." $cwd/worker.php");
        
$desc = array();
        
$proc proc_open($cmd$desc$pipesNULLNULL);
        
proc_close($proc);
    }

}

?>