Пример #1
0
 /**
  * Creates a downloadable file from the given table of the users database
  * @param string $table table in the users database
  * @param string $suffix
  * @return array $response
  */
 private function _createDownloadFile($table, $format, $regen = false)
 {
     // sanity check for format
     if (!in_array($format, Daiquiri_Config::getInstance()->query->download->adapter->enabled->toArray())) {
         throw new Exception('Error: format not valid.');
     }
     // create link and file sysytem path for table dump
     $username = Daiquiri_Auth::getInstance()->getCurrentUsername();
     $suffix = Daiquiri_Config::getInstance()->query->download->adapter->config->{$format}->suffix;
     $filename = $this->_generateFileName($table, $suffix);
     $url = '/query/download/file?table=' . $table . '&format=' . $format;
     $dir = Daiquiri_Config::getInstance()->query->download->dir . DIRECTORY_SEPARATOR . $username;
     $file = $dir . DIRECTORY_SEPARATOR . $filename;
     // get queue type and validate
     $queueType = strtolower(Daiquiri_Config::getInstance()->query->download->type);
     if ($queueType !== "direct" and $queueType !== "gearman") {
         throw new Exception('Download queue type not valid');
     }
     // create dir if neccessary
     if (!is_dir($dir)) {
         if (mkdir($dir) === false) {
             return array('status' => 'error', 'error' => 'Configuration of download directory wrong, please contact support.');
         }
         chmod($dir, 0775);
     }
     // delete the old file if regen is set
     if ($regen === true) {
         if (file_exists($file . ".lock")) {
             throw new Daiquiri_Exception_Forbidden();
         }
         // delete the files...
         if (file_exists($file)) {
             unlink($file);
         }
         if (file_exists($file . ".err")) {
             unlink($file . ".err");
         }
     }
     if (!file_exists($file) && ($queueType === "direct" || empty($queueType))) {
         //get the user db name
         $username = Daiquiri_Auth::getInstance()->getCurrentUsername();
         $db = Daiquiri_Config::getInstance()->getUserDbName($username);
         // get the resource and create dump
         $resource = new Data_Model_Resource_Viewer();
         $resource->init($db, $table);
         try {
             $resource->dumpTable($format, $file);
         } catch (Exception $e) {
             return array('status' => 'error', 'error' => array('form' => $e->getMessage() . ' Please contact support.'));
         }
     }
     if ((!file_exists($file) || file_exists($file . ".lock")) && $queueType === "gearman") {
         // check if gearman is up and running
         exec('pgrep gearmand', $output, $return);
         if ($return != 0) {
             throw new Exception('gearmand is not running.');
         }
         // check if
         $restartGeamanManager = false;
         $pidfile = Daiquiri_Config::getInstance()->query->download->gearman->pid;
         if (file_exists($pidfile)) {
             $pid = file_get_contents($pidfile);
             exec('ps -p ' . $pid, $output, $return);
             if ($return != 0) {
                 $restartGeamanManager = true;
             }
         } else {
             $restartGeamanManager = true;
         }
         if ($restartGeamanManager) {
             // check if we have write access to actually create this PID file
             if (!is_writable(dirname(Daiquiri_Config::getInstance()->query->download->gearman->pid))) {
                 return array('status' => 'error', 'error' => 'Cannot write to the gearman PID file, please contact support.');
             }
             $gearmanConf = Daiquiri_Config::getInstance()->query->download->gearman;
             // not there, start GearmanManager
             $cmd = escapeshellcmd($gearmanConf->manager) . ' -d' . ' -D ' . escapeshellcmd($gearmanConf->numThread) . ' -h ' . escapeshellcmd($gearmanConf->host) . ':' . escapeshellcmd($gearmanConf->port) . ' -P ' . escapeshellcmd($gearmanConf->pid) . ' -w ' . escapeshellcmd($gearmanConf->workerDir) . ' -r 1 > /tmp/Daiquiri_GearmanManager.log &';
             shell_exec($cmd);
             // DOES NOT WORK IN NEWER PHP, NEED TO BE FIXED
             // http://stackoverflow.com/questions/12322811/call-time-pass-by-reference-has-been-removed
             // check if pid exists, if not, an error occured - wait for 10 seconds to start gearman manager
             $count = 0;
             while (!file_exists($gearmanConf->pid)) {
                 $count += 1;
                 sleep(1);
                 if ($count > 10) {
                     throw new Exception('Error: Could not start GearmanManager.');
                 }
             }
         }
         // check if lockfile is present and if not, create
         if (!file_exists($file . ".lock")) {
             if (file_exists($file . ".err")) {
                 return array('status' => 'error', 'error' => 'An error file exists on the server, please contact support.');
             }
             // write lock file
             touch($file . ".lock");
             // get the user db name
             $username = Daiquiri_Auth::getInstance()->getCurrentUsername();
             $db = Daiquiri_Config::getInstance()->getUserDbName($username);
             // get the resource and create dump
             $resource = new Data_Model_Resource_Viewer();
             $resource->init($db, $table);
             try {
                 $resource->dumpTableGearman($format, $file);
             } catch (Exception $e) {
                 unlink($file . ".lock");
                 return array('status' => 'error', 'error' => array('form' => $e->getMessage() . ' Please contact support.'));
             }
             return array('status' => 'pending', 'format' => $format);
         } else {
             return array('status' => 'pending', 'format' => $format);
         }
     }
     return array('status' => 'ok', 'link' => Daiquiri_Config::getInstance()->getSiteUrl() . $url, 'format' => $format);
 }