騰訊雲資料庫團隊:phpMyAdmin中sql-parser組件的使用

来源:http://www.cnblogs.com/qcloud1001/archive/2017/03/15/6553239.html
-Advertisement-
Play Games

phpMyAdmin的程式主要使用php和javascript開發,它的安裝使用都比較簡單而且已有很多相關介紹,今天來自騰訊雲資料庫團隊的高級開發工程師在此給大家介紹一下——源碼中的一個核心組件sql-parser ...


phpMyAdmin是一款基於Web端運行的開源資料庫管理工具,支持管理MySQL和MariaDB兩種資料庫。 phpMyAdmin的程式主要使用php和javascript開發,它的安裝使用都比較簡單而且已有很多相關介紹不再重覆,今天要介紹的是源碼中的一個核心組件sql-parser。

sql-parser簡介

sql-parser組件的主要用途是對SQL語句進行詞法分析、語法分析,繼而可以實現對SQL語句的解構、加工、替換、再組裝等需求,另外也可以對SQL進行highlight等處理。sql-parser由純PHP語言實現,同時也是整個phpMyAdmin源碼中為數不多的代碼架構比較清晰且符合當前PHP界PSR標準規範的模塊。

sql-parser組件安裝

需事先安裝好php,git客戶端,以及composer php包管理工具

margin@margin-MB1:~/tmp$ sudo git clone https://github.com/phpmyadmin/sql-parser.git

margin@margin-MB1:~/tmp$ cd sql-parser && sudo composer install

組件安裝完畢,下麵介紹具體的調用

解析普通語句

<?php
require_once '../sql-parser/vendor/autoload.php';
use SqlParser\Parser;

$query = 'SELECT * FROM t1 LEFT JOIN (t2, t3, t4) '
    . 'ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)';

$parser = new Parser($query);
$stmt = $parser->statements[0];
echo json_encode($stmt);

運行結果中$parser變數是一個大對象,裡面存儲有對$query語句的詞法分析結果$query->list,語法分析結果$query-statements,以及錯誤信息等。 其中$query-statements的結構如下:

{"expr":
[{"database":null,"table":null,"column":null,"expr":"*","alias":null,"function":n
ull,"subquery":null}],"from":
[{"database":null,"table":"t1","column":null,"expr":"t1","alias":null,"function":
null,"subquery":null}],"partition":null,"where":null,"group":null,"having":null,"
order":null,"limit":null,"procedure":null,"into":null,"join":
[{"type":"LEFT","expr":{"database":null,"table":null,"column":null,"expr":"(t2, 
t3, t4)","alias":null,"function":null,"subquery":null},"on":[{"identifiers":
["t2","a","t1"],"isOperator":false,"expr":"(t2.a=t1.a"},{"identifiers":
[],"isOperator":true,"expr":"AND"},{"identifiers":
["t3","b","t1"],"isOperator":false,"expr":"t3.b=t1.b"},{"identifiers":
[],"isOperator":true,"expr":"AND"},{"identifiers":
["t4","c","t1"],"isOperator":false,"expr":"t4.c=t1.c)"}],"using":null}],"union":
[],"options":{"options":[]},"first":0,"last":50}

解析事務

require_once '../sql-parser/vendor/autoload.php';
use SqlParser\Parser;

$query = 'START TRANSACTION;' .
    'SELECT @A:=SUM(salary) FROM table1 WHERE type=1;' .
    'UPDATE table2 SET summary=@A WHERE type=1;' .
    'COMMIT;';

$parser = new Parser($query);
$stmt = $parser->statements[0];
echo json_encode($stmt);

輸出結果:

{"type":1,"statements":[{"expr":
[{"database":null,"table":null,"column":null,"expr":"@A:=SUM(salary)","alias":nul
l,"function":"SUM","subquery":null}],"from":
[{"database":null,"table":"table1","column":null,"expr":"table1","alias":null,"fu
nction":null,"subquery":null}],"partition":null,"where":[{"identifiers":
["type"],"isOperator":false,"expr":"type=1"}],"group":null,"having":null,"order":
null,"limit":null,"procedure":null,"into":null,"join":null,"union":[],"options":
{"options":[]},"first":1,"last":19},{"tables":
[{"database":null,"table":"table2","column":null,"expr":"table2","alias":null,"fu
nction":null,"subquery":null}],"set":[{"column":"summary","value":"@A"}],"where":
[{"identifiers":
["type"],"isOperator":false,"expr":"type=1"}],"order":null,"limit":null,"options"
:{"options":[]},"first":20,"last":35}],"end":
{"type":2,"statements":null,"end":null,"options":{"options":
{"1":"COMMIT"}},"first":36,"last":37},"options":{"options":{"1":"START 
TRANSACTION"}},"first":0,"last":0}

除以上兩種語句之外,sql-parser還支持解析存儲過程等幾乎所有MySQL語法,不再一一舉例。下麵是其SQL構造器的用法舉例。

組裝SQL語句

組裝select語句:

<?php

require_once '../sql-parser/vendor/autoload.php';

use SqlParser\Components\OptionsArray;
use SqlParser\Components\Expression;
use SqlParser\Components\Condition;
use SqlParser\Components\Limit;
use SqlParser\Statements\SelectStatement;

$stmt = new SelectStatement();

$stmt->options = new OptionsArray(array('DISTINCT'));

$stmt->expr[] = new Expression('sakila', 'film', 'film_id', 'fid');
$stmt->expr[] = new Expression('COUNT(film_id)');
$stmt->from[] = new Expression('', 'film', '');
$stmt->from[] = new Expression('', 'actor', '');
$stmt->where[] = new Condition('film_id > 10');
$stmt->where[] = new Condition('OR');
$stmt->where[] = new Condition('actor.age > 25');
$stmt->limit = new Limit(1, 10);

var_dump($stmt->build());

輸出結果:

margin@margin-MB1:~/code/parserTest$ php build.php 
string(137) "SELECT DISTINCT `sakila`.`film`.`film_id` AS `fid`, COUNT(film_id) 
FROM `film`, `actor` WHERE film_id > 10 OR actor.age > 25 LIMIT 10, 1 "

組裝觸發器語句:

<?php
require_once '../sql-parser/vendor/autoload.php';

use SqlParser\Components\Expression;
use SqlParser\Components\OptionsArray;
use SqlParser\Statements\CreateStatement;

$stmt = new CreateStatement();

$stmt->options = new OptionsArray(array('TRIGGER'));
$stmt->name = new Expression('ins_sum');
$stmt->entityOptions = new OptionsArray(array('BEFORE', 'INSERT'));
$stmt->table = new Expression('account');
$stmt->body = 'SET @sum = @sum + NEW.amount';

var_dump($stmt->build());

輸出結果:

margin@margin-MB1:~/code/parserTest$ php build.php 
string(89) "CREATE TRIGGER ins_sum BEFORE INSERT ON account FOR EACH ROW SET @sum 
= @sum + NEW.amount"

SQL再加工

多條語句一起加工處理:

<?php
require_once '../sql-parser/vendor/autoload.php';

use SqlParser\Parser;
use SqlParser\Components\Expression;

$query  = <<&lt;STR
ALTER TABLE `tbl` CHANGE `uid` `uid` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `tbl` CHANGE `field_1` `field_2` INT( 10 ) UNSIGNED NOT NULL;
select * from tbl3 where id = 3
STR;

$parser = new Parser($query);

//處理第一條語句
$statement_0 = $parser-&gt;statements[0];
$statement_0->table  = new Expression(
    'db2', 'tb2', ''
);
var_dump($statement_0->build());

//處理第二條語句
$statement_1 = $parser->statements[1];
$statement_1->table  = new Expression(
    'db3', 'tb3', ''
);
var_dump($statement_1->build());

輸出結果:

margin@margin-MB1:~/code/parserTest$ php build.php 
string(85) "ALTER TABLE `db2`.`tb2` CHANGE `uid` `uid` INT( 10 ) UNSIGNED NOT 
NULL AUTO_INCREMENT"
string(78) "ALTER TABLE `db3`.`tb3` CHANGE `field_1` `field_2` INT( 10 ) UNSIGNED 
NOT NULL"

以上是sql-parser組件一些基本的用法示例,phpMyAdmin的sql-parser組件功能比較豐富和完備,本文限了篇幅不能詳盡,有興趣的讀者可以通過閱讀源碼來瞭解更多高級的用法。

 

相關推薦

什麼是雲資料庫MySQL?
存儲總量達20T的MySQL實例,如何完成遷移?
CDB for MySQL相關文檔


此文已由作者授權騰訊雲技術社區發佈,轉載請註明文章出處,獲取更多雲計算技術乾貨,可請前往騰訊雲技術社區

歡迎大家關註騰訊雲技術社區-博客園官方主頁,我們將持續在博客園為大家推薦技術精品文章哦~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 指定移動的像素的上偏移值 //實現男、女的單選控制項 ...
  • 轉載請標明出處: "http://www.cnblogs.com/why168888/p/6548544.html" 本文出自: "【Edwin博客園】" 如何簽名: jarsgner verbose keystore[keystorePath] singnedjar [apkOut] [apkln ...
  • 偶爾才用一次的JEB, 出現 “Controller沒有響應或者無法訪問, JEB即將終止.” 也懶得去逆了。直接用ProcessHacker找到對應的線程掛起即可。當然這隻是臨時的辦法。。我也只是臨時用用。有興趣的自己做工具吧。 ...
  • Swift _ OC _ 混編 在OC環境下使用Swift. "GitHub源碼" ...
  • 前言 自Weex發佈伊始, 其口號 "Write Once, Run Everywhere"就吸引了大批前端與客戶端程式猿紛紛入坑, 我也不能獨善其中. 就我目前所學習Weex的經驗在此記錄一下, 由於我是一名剛入行不久iOS開發者, 所以這篇博客含金量不高, 下麵就簡單闡述下如何將Weex初步集成 ...
  • CoreAnimation 寄宿圖 博客園makedown支持不佳,如有需要請進 "GitHub" . 寄宿圖:圖層中所包含的圖 by:旭寶愛吃魚     針對於寄宿圖我在這裡只討論contents屬性以及Custom Drawing. contents &n ...
  • 在移動互聯網領域蓬勃發展的今天,APP的性能也成為各大公司重點關註的方向,該系列文章主要針對iOS的性能的幾個方面做一些研究。 什麼是HTTP2.0? 什麼是HTTP2.0? 網上很容易搜到關於HTTP2.0的概念的文章,這裡不再累述。 蘋果從iOS9開始支持HTTP2.0,對iOS開發人員來說,即 ...
  • 本文主要講述了在FineReport移動端中釘釘如何集成設計器的插件從而實現企業應用。 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...