sequelize 是 Node 中使用比較多的一個 ORM 庫,最近計劃將項目中的 sequelize
升級至 V5 版本。javascript
根據 升級文檔,其中一項是即將禁用 String based operators
,使用 Sequelize.Op 等 Symbol operators 來代替。html
而 operator
主要用在查詢條件中,用以生成查詢條件,如java
const where = {
age: {
$lte: 10
}
}
// 替換爲
const replaceWhere = {
age: {
[Op.lte]: 10
}
}
複製代碼
const operatorsAliases = {
$eq: Op.eq,
$ne: Op.ne,
$gte: Op.gte,
$all: Op.all,
$in: Op.in,
...moreAliase
}
複製代碼
簡而言之,須要把本項目中的全部查詢條件, 從 operatorsAliases
左邊的替換爲右邊的。這也是本篇文章的主要內容git
本文連接: shanyue.tech/post/sequel…github
在開始工做以前,須要先把 git 的工做區和暫存區清理乾淨,避免替換過程當中形成沒法回退的尷尬局面。正則表達式
把工做區和暫存區清理乾淨的意思就是,先把能 commit 的 commit 掉,不能 commit 的 stash 掉,固然切個新分支就更好了。shell
在剛開始隨手手動替換了幾個以後,以爲這樣也不是辦法,決定開始使用 VS Code
的全局替換。vim
首先思考一個查詢的 operator 會出現的位置,無外乎如下幾種瀏覽器
where.age = { $lte: 10 }
where.age.$lte = 10
where.age['$lte'] = 10
複製代碼
另外,順序很重要,從最具體到抽象的順序以下bash
['$lte', Op.lte],
['.$lte', [Op.lte]],
['$lte', [Op.lte]]
複製代碼
而後,按照順序挨個替換就行了,但替換了幾個知乎,我發現...個人耐心實在有限
> Object.keys(operatorsAliases).length
34
複製代碼
我須要替換 34 * 3 = 102
次,這也不能怪我煩啊,擱誰誰都沒有耐心
多掌握一個命令是多麼重要
先來一個 hello, world
版的 sed 命令,如下命令把 hello
替換成 word
恩,sed
替換的語法和 vim
簡直如出一轍,這告訴咱們掌握 vim
多麼重要...
$ echo hello | sed "s/hello/world/g"
world
複製代碼
根據上一部分所講的規則,寫一個 sed 文件 (replace.sed),對示例(test.js)作一個測試
# replace.sed
s/'$lte'/Op.lte/g
s/.$lte/[Op.lte]/g
s/$lte/[Op.lte]/g
複製代碼
where.age = { $lte: 10 }
where.age.$lte = 10
where.age['$lte'] = 10
複製代碼
作了簡單的測試,輸入如下命令,看起來工做地還不錯
$ sed -f replace.sed test.js
where.age = {[Op.lte]: 10 }
where.age[Op.lte] = 10
where.age[Op.lte] = 10
複製代碼
可是有 34 個 alias 須要替換,利用瀏覽器的控制檯生成 sed 文件
> Object.keys(operatorsAliases).map(op => op.slice(1)).flatMap(op => [`s/'\$${op}\b'/Op.${op}/g`, `s/\.\$${op}\b/[Op.${op}]/g`, `s/\$${op}\b/[Op.${op}]/g`]).join('\n')
s/'$eq'/Op.eq/g
s/.$eq/[Op.eq]/g
s/$eq/[Op.eq]/g
s/'$ne'/Op.ne/g
s/.$ne/[Op.ne]/g
s/$ne/[Op.ne]/g
...
...
複製代碼
雖然生成的命令有些簡單粗暴...,不過簡單粗暴的東西就是好用
只剩下一個問題,如何列出當前路徑下的全部文件
多掌握一個命令是多麼重要
我把全部我能想到的命令給列下來
find .
應該能夠排除掉 .gitignores 所列文件,但好像有點麻煩,我歷來沒用過。ls -R
格式不夠友好tree
可讀性不錯,但機器可讀性太差了如何排除文件夾能夠參考 How to exclude a directory in find . command
以上三個命令都不太好用。柳暗花明又一村,這裏有一個更簡單而又恰到好處的命令
git ls-files
複製代碼
關於 git 的更多命令,能夠參考 Git Cheat Sheets
此時,shell 命令以下,-i 表明直接替換文件,-i ""
表明替換時文件名不添加後綴,爲啥必定要寫個空字符串,由於 MAC 下的 sed 命令就是如此喪心病狂。
$ sed -i "" -f replace.sed $(git ls-files)
複製代碼
不過,這時候有新的問題產生了,在 git diff
時發現有一些模板中帶有 $index
,也會被替換成 [Op.in]dex
,這是不指望的結果
git checkout .
複製代碼
使用 \b 匹配單詞,完美解決問題。
s/'\$eq\b'/Op.eq/g
s/\.\$eq\b/[Op.eq]/g
s/\$eq\b/[Op.eq]/g
複製代碼
不過,在 MAC 下並不支持 \b
,能夠拿如下命令作個試驗。這時候在 MAC 下須要安裝 gnu-sed
,終於把 MAC 下的 sed
命令替換掉了
$ echo "hello" | sed "s/\bhello\b/world/g"
hello
$ brew install gnu-sed
$ echo "hello" | gsed "s/\bhello\b/world/g"
world
# 必定必定要用雙引號括起來
$ echo "hello" | gsed s/\bhello\b/world/g
hello
複製代碼
這裏有一個很重要的點,即sed命令必定要用雙引號給括起來
使用 js 生成新的 sed 命令
Object.keys(operatorsAliases).map(op => op.slice(1)).flatMap(op => [`s/'\\$${op}\\b'/Op.${op}/g`, `s/\\.\\$${op}\\b/[Op.${op}]/g`, `s/\\$${op}\\b/[Op.${op}]/g`]).join('\n')
複製代碼
最後執行命令,成功替換所有字符
# -i 表明直接替換文件,-r 表明支持擴展的正則表達式
$ gsed -i -r -f r.sed $(git ls-files| grep -v src/data)
$ git diff --shortstat
63 files changed, 293 insertions(+), 293 deletions(-)
複製代碼
歡迎關注個人公衆號山月行,在這裏記錄着個人技術成長,歡迎交流