* [misc] move install duckdb to bi model.
This commit is contained in:
+119
-50
@@ -1367,79 +1367,148 @@ class biModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* Query sql.
|
||||
* 下载duckdb引擎。
|
||||
* Download duckdb.
|
||||
*
|
||||
* @param string $sql
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return object
|
||||
* @return string
|
||||
*/
|
||||
/*
|
||||
public function querySql($sql, $recPerPage = 100, $pageID = 1)
|
||||
public function downloadDuckdb(): string
|
||||
{
|
||||
$queryResult = new stdclass();
|
||||
$queryResult->error = false;
|
||||
$queryResult->errorMsg = '';
|
||||
$queryResult->cols = array();
|
||||
$queryResult->rows = array();
|
||||
$queryResult->sql = '';
|
||||
$queryResult->fieldSettings = array();
|
||||
$checkDuckdb = $this->updateDownloadingTagFile('file', 'check');
|
||||
$checkExtension = $this->updateDownloadingTagFile('extension', 'check');
|
||||
|
||||
$sql = $this->processVars($sql);
|
||||
if($checkDuckdb == 'loading' || $checkExtension == 'loading') return 'loading';
|
||||
|
||||
$statement = $this->sql2Statement($sql);
|
||||
if(is_string($statement))
|
||||
{
|
||||
$queryResult->error = true;
|
||||
$queryResult->errorMsg = $statement;
|
||||
$this->loadModel('bi');
|
||||
$binRoot = $this->app->getTmpRoot() . 'duckdb' . DS;
|
||||
$duckdbBin = $this->getDuckdbBinConfig();
|
||||
|
||||
return $queryResult;
|
||||
}
|
||||
$duckdbUrl = $duckdbBin['fileUrl'];
|
||||
$extensionUrl = $duckdbBin['extensionUrl'];
|
||||
|
||||
$checked = $this->validateSql($sql);
|
||||
if($checked !== true)
|
||||
{
|
||||
$queryResult->error = true;
|
||||
$queryResult->errorMsg = $checked;
|
||||
$this->updateDownloadingTagFile('file', 'create');
|
||||
$this->updateDownloadingTagFile('extension', 'create');
|
||||
|
||||
return $queryResult;
|
||||
}
|
||||
$downloadDuckdb = $this->downloadFile($duckdbUrl, $binRoot, $duckdbBin['file']);
|
||||
$downloadExtension = $this->downloadFile($extensionUrl, $binRoot, $duckdbBin['extension']);
|
||||
|
||||
$limitSql = $this->prepareSqlPager($statement, $recPerPage, $pageID);
|
||||
$this->updateDownloadingTagFile('file', 'remove');
|
||||
$this->updateDownloadingTagFile('extension', 'remove');
|
||||
|
||||
try
|
||||
return $downloadDuckdb && $downloadExtension ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新tab文件下载状态。
|
||||
* Update downloading tab file status.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $action
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function updateDownloadingTagFile(string $type = 'file', string $action = 'create'): string
|
||||
{
|
||||
$downloading = '.downloading';
|
||||
$binRoot = $this->app->getTmpRoot() . 'duckdb' . DS;
|
||||
$duckdbBin = $this->getDuckdbBinConfig();
|
||||
$file = $binRoot . $duckdbBin[$type];
|
||||
$tagFile = $file . $downloading;
|
||||
|
||||
if($action == 'create')
|
||||
{
|
||||
if(file_exists($tagFile)) return 'fail';
|
||||
file_put_contents($tagFile, 'Downloading...');
|
||||
return 'ok';
|
||||
}
|
||||
|
||||
if($action == 'check')
|
||||
{
|
||||
$queryResult->rows = $this->dbh->query($limitSql)->fetchAll();
|
||||
$queryResult->rowsCount = $this->dbh->query("SELECT FOUND_ROWS() as count")->fetch()->count;
|
||||
if(file_exists($file)) return 'ok';
|
||||
if(file_exists($tagFile)) return 'loading';
|
||||
return 'fail';
|
||||
}
|
||||
catch(Exception $e)
|
||||
if($action == 'remove')
|
||||
{
|
||||
$queryResult->error = true;
|
||||
$queryResult->errorMsg = $e;
|
||||
if(!file_exists($tagFile)) return 'fail';
|
||||
unlink($tagFile);
|
||||
}
|
||||
return 'ok';
|
||||
}
|
||||
|
||||
/**
|
||||
* 解压文件。
|
||||
* Unzip file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $file
|
||||
* @param string $extractFile
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function unzipFile(string $path, string $file, string $extractFile): bool
|
||||
{
|
||||
$this->app->loadClass('pclzip', true);
|
||||
$zip = new pclzip($file);
|
||||
|
||||
/* 限制解压的文件内容以阻止 ZIP 解压缩的目录穿越漏洞。*/
|
||||
/* Limit the file content to prevent the directory traversal vulnerability of ZIP decompression. */
|
||||
$extractFiles = array($extractFile);
|
||||
return $zip->extract(PCLZIP_OPT_PATH, $path, PCLZIP_OPT_BY_NAME, $extractFiles) === 0;
|
||||
}
|
||||
|
||||
return $queryResult;
|
||||
/**
|
||||
* 下载文件。
|
||||
* Download file.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $savePath
|
||||
* @param string $finalFile
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function downloadFile(string $url, string $savePath, string $finalFile): bool
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
$fileContents = curl_exec($ch);
|
||||
|
||||
if (curl_errno($ch))
|
||||
{
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
$columns = $this->prepareColumns($limitSql, $statement);
|
||||
$clientLang = $this->app->getClientLang();
|
||||
$result = json_decode($fileContents, true);
|
||||
if(isset($result['error']))
|
||||
{
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
$fieldSettings = array();
|
||||
foreach($columns as $field => $settings)
|
||||
$filename = basename($url);
|
||||
$filename = $savePath . $filename;
|
||||
$result = file_put_contents($filename, $fileContents);
|
||||
if($result === false)
|
||||
{
|
||||
$title = $settings['name'];
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
chmod($filename, 0755);
|
||||
|
||||
if(!isset($settings[$clientLang]) || empty($settings[$clientLang])) $settings[$clientLang] = $title;
|
||||
$fieldSettings[$field] = $settings;
|
||||
if(pathinfo($filename, PATHINFO_EXTENSION) === 'zip')
|
||||
{
|
||||
$this->unzipFile($savePath, $filename, $finalFile);
|
||||
unlink($filename);
|
||||
}
|
||||
|
||||
$queryResult->cols = $this->buildQueryResultTableColumns($fieldSettings);
|
||||
$queryResult->fieldSettings = $fieldSettings;
|
||||
$queryResult->sql = $limitSql;
|
||||
|
||||
return $queryResult;
|
||||
return chmod($savePath . $finalFile, 0755);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encode json.
|
||||
|
||||
@@ -99,8 +99,9 @@ class install extends control
|
||||
$this->view->dataRootResult = $this->installZen->checkDataRoot();
|
||||
$this->view->iniInfo = $this->install->getIniInfo();
|
||||
|
||||
$checkDuckdb = $this->updateDownloadingTagFile('file', 'check');
|
||||
$checkExtension = $this->updateDownloadingTagFile('extension', 'check');
|
||||
$this->loadModel('bi');
|
||||
$checkDuckdb = $this->bi->updateDownloadingTagFile('file', 'check');
|
||||
$checkExtension = $this->bi->updateDownloadingTagFile('extension', 'check');
|
||||
$this->view->duckdbResult = $checkDuckdb == 'ok' && $checkExtension == 'ok' ? 'ok' : 'fail';
|
||||
|
||||
$checkSession = ini_get('session.save_handler') == 'files';
|
||||
@@ -637,8 +638,9 @@ class install extends control
|
||||
*/
|
||||
public function installDuckdb()
|
||||
{
|
||||
$this->updateDownloadingTagFile('file', 'remove');
|
||||
$this->updateDownloadingTagFile('extension', 'remove');
|
||||
$this->loadModel('bi');
|
||||
$this->bi->updateDownloadingTagFile('file', 'remove');
|
||||
$this->bi->updateDownloadingTagFile('extension', 'remove');
|
||||
|
||||
$this->view->title = $this->lang->install->installDuckdb;
|
||||
$this->view->duckdbStatus = 'loading';
|
||||
@@ -658,7 +660,7 @@ class install extends control
|
||||
ignore_user_abort(true);
|
||||
set_time_limit(0);
|
||||
session_write_close();
|
||||
$this->installZen->downloadDuckdb();
|
||||
$this->loadModel('bi')->downloadDuckdb();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -670,8 +672,9 @@ class install extends control
|
||||
*/
|
||||
public function ajaxCheckDuckdb()
|
||||
{
|
||||
$checkDuckdb = $this->updateDownloadingTagFile('file', 'check');
|
||||
$checkExtension = $this->updateDownloadingTagFile('extension', 'check');
|
||||
$this->loadModel('bi');
|
||||
$checkDuckdb = $this->bi->updateDownloadingTagFile('file', 'check');
|
||||
$checkExtension = $this->bi->updateDownloadingTagFile('extension', 'check');
|
||||
|
||||
echo(json_encode(array('duckdb' => $checkDuckdb, 'extension' => $checkExtension)));
|
||||
}
|
||||
|
||||
@@ -249,152 +249,6 @@ class installZen extends install
|
||||
return is_dir($dataRoot) && is_writable($dataRoot) ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载duckdb引擎。
|
||||
* Download duckdb.
|
||||
*
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected function downloadDuckdb(): string
|
||||
{
|
||||
$checkDuckdb = $this->updateDownloadingTagFile('file', 'check');
|
||||
$checkExtension = $this->updateDownloadingTagFile('extension', 'check');
|
||||
|
||||
if($checkDuckdb == 'loading' || $checkExtension == 'loading') return 'loading';
|
||||
|
||||
$this->loadModel('bi');
|
||||
$binRoot = $this->app->getTmpRoot() . 'duckdb' . DS;
|
||||
$duckdbBin = $this->bi->getDuckdbBinConfig();
|
||||
|
||||
$duckdbUrl = $duckdbBin['fileUrl'];
|
||||
$extensionUrl = $duckdbBin['extensionUrl'];
|
||||
|
||||
$this->updateDownloadingTagFile('file', 'create');
|
||||
$this->updateDownloadingTagFile('extension', 'create');
|
||||
|
||||
$downloadDuckdb = $this->downloadFile($duckdbUrl, $binRoot, $duckdbBin['file']);
|
||||
$downloadExtension = $this->downloadFile($extensionUrl, $binRoot, $duckdbBin['extension']);
|
||||
|
||||
$this->updateDownloadingTagFile('file', 'remove');
|
||||
$this->updateDownloadingTagFile('extension', 'remove');
|
||||
|
||||
return $downloadDuckdb && $downloadExtension ? 'ok' : 'fail';
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新tab文件下载状态。
|
||||
* Update downloading tab file status.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $action
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected function updateDownloadingTagFile(string $type = 'file', string $action = 'create'): string
|
||||
{
|
||||
$this->loadModel('bi');
|
||||
|
||||
$downloading = '.downloading';
|
||||
$binRoot = $this->app->getTmpRoot() . 'duckdb' . DS;
|
||||
$duckdbBin = $this->bi->getDuckdbBinConfig();
|
||||
$file = $binRoot . $duckdbBin[$type];
|
||||
$tagFile = $file . $downloading;
|
||||
|
||||
if($action == 'create')
|
||||
{
|
||||
if(file_exists($tagFile)) return 'fail';
|
||||
file_put_contents($tagFile, 'Downloading...');
|
||||
return 'ok';
|
||||
}
|
||||
|
||||
if($action == 'check')
|
||||
{
|
||||
if(file_exists($file)) return 'ok';
|
||||
if(file_exists($tagFile)) return 'loading';
|
||||
return 'fail';
|
||||
}
|
||||
if($action == 'remove')
|
||||
{
|
||||
if(!file_exists($tagFile)) return 'fail';
|
||||
unlink($tagFile);
|
||||
}
|
||||
return 'ok';
|
||||
}
|
||||
|
||||
/**
|
||||
* 解压文件。
|
||||
* Unzip file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $file
|
||||
* @param string $extractFile
|
||||
* @access protected
|
||||
* @return bool
|
||||
*/
|
||||
protected function unzipFile(string $path, string $file, string $extractFile): bool
|
||||
{
|
||||
$this->app->loadClass('pclzip', true);
|
||||
$zip = new pclzip($file);
|
||||
|
||||
/* 限制解压的文件内容以阻止 ZIP 解压缩的目录穿越漏洞。*/
|
||||
/* Limit the file content to prevent the directory traversal vulnerability of ZIP decompression. */
|
||||
$extractFiles = array($extractFile);
|
||||
return $zip->extract(PCLZIP_OPT_PATH, $path, PCLZIP_OPT_BY_NAME, $extractFiles) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件。
|
||||
* Download file.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $savePath
|
||||
* @param string $finalFile
|
||||
* @access protected
|
||||
* @return bool
|
||||
*/
|
||||
protected function downloadFile(string $url, string $savePath, string $finalFile): bool
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
$fileContents = curl_exec($ch);
|
||||
|
||||
if (curl_errno($ch))
|
||||
{
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = json_decode($fileContents, true);
|
||||
if(isset($result['error']))
|
||||
{
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
$filename = basename($url);
|
||||
$filename = $savePath . $filename;
|
||||
$result = file_put_contents($filename, $fileContents);
|
||||
if($result === false)
|
||||
{
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
chmod($filename, 0755);
|
||||
|
||||
if(pathinfo($filename, PATHINFO_EXTENSION) === 'zip')
|
||||
{
|
||||
$this->unzipFile($savePath, $filename, $finalFile);
|
||||
unlink($filename);
|
||||
}
|
||||
|
||||
return chmod($savePath . $finalFile, 0755);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查数据库配置信息的正确性。
|
||||
* Check config ok or not.
|
||||
|
||||
Reference in New Issue
Block a user