EdgeDB有許多令我驚豔的特點,今天的內容將分享四個我於無間EdgeDB
中最喜歡的功能,前兩個與SDL有關,後兩個則與EdgeQL有關。最後,於文末附上此系列文的參賽心得。
CIBTeamTreat
是一個下午茶抽獎系統,用來決定部門主管需不需要請大家吃下午茶。 其利用sequence
來自動產生每次抽獎的流水號,並針對CIB部門的每位同事,利用 link properties
來隨機產生1~10的數字。
scalar type TeamTreatNumber extending sequence;
type CIBTeamTreat {
required team_treat_number: TeamTreatNumber {
constraint exclusive;
default := sequence_next(introspect TeamTreatNumber);
}
multi colleagues: Police {
default:= (select Police filter .dept="刑事情報科(CIB)");
readonly := true;
point: int64 {
default:= <int64>math::ceil(random()*10)
}
};
team_treat:= max(.colleagues@point) >= 9
}
抽獎系統的使用方式也相當簡單,一行query即可完成:
select(insert CIBTeamTreat).team_treat;
Envelope
在本劇中是一個特別的物件,我們希望這個物件是獨一無二地存在。使用 Access Policies
可以輕鬆達成這個要求,僅需在insert
時,檢查Envelope object
是否已經存在即可。能夠將商業邏輯併入在schema中,是EdgeDB獨樹一格的地方。試想如果EdgeDB沒有此項功能,這個偵測Envelope object
是否存在的檢查,將必須由使用者依照所使用的程式語言來實現,這將是一個繁複且易錯的環節。
type Envelope {
name: str {
default:= "標";
readonly:= true
};
access policy allow_select_insert_delete
allow select, insert, delete;
access policy only_one_envelope_exists
deny insert
using (exists Envelope)
{
errmessage := 'Only one Envelope can be existed.'
};
}
Backlinks
搭配使用nested shape construction
,可以組合出威力強大的deep fetching
。例如beverages
原先並不在lau object
內,但我們使用:= 將.<consumed_by[is Beverage]
定義beverages
為computed backlink
,最後使用 {name, where : {name}}
,得到deep fetching
的結果。
select lau {
name,
nickname,
beverages:= .<consumed_by[is Beverage] {
name,
where : {name}
}
};
{
default::GangsterSpy {
name: '劉建明',
nickname: '劉仔',
beverages: {
default::Beverage
{
name: '熱奶茶',
where: default::Landmark {name: '警察局'}
},
default::Beverage
{
name: '綠茶',
where: default::Location {name: '大廈三樓'}
},
},
},
}
所有的top-level EdgeQL statements包括(select
、insert
、update
及delete
)全部都支援with
區塊的使用。在with
區塊內定義於後面的變數,可以引用前面的變數,例如names
可以引用police_names
及police_spy_names
。此外,在with
區塊中可以暫時轉變預設的module
,例如module ext::pg_trgm
, 即是將預設module
由default
暫時轉變為ext::pg_trgm
。這個概念和Python的context manager非常相似。
with police_names:= Police.name,
police_spy_names:= PoliceSpy.name,
names:= array_join(array_agg(police_names union police_spy_names), " "),
module ext::pg_trgm,
select word_similarity("陳永仨", names);
如果您在觀看此系列文後,有了想學習EdgeDB的動力,我倍感榮幸。有關您之後的EdgeDB學習之路,我會建議在閱讀完David(註1)所寫的Easy EdgeDB後,找一個您有興趣的故事來練習,就像我選擇無間道一樣。在練習的過程中,一定會遇到許多困難,此時再來參考官方文件的說明、重溫本系列文或Easy EdgeDB
中相關的內容。使用EdgeDB來描述各種事物的「沉浸式」學習法,讓我很享受這趟旅程,推薦給您。
此外,本系列文中只舉了如何搭配Python與Rust來使用EdgeDB,其實EdgeDB還支援許多程式語言,尤其是JavaScript/TypeScript的支援尤佳,很多功能都優先開發。大家可以看看今年EdgeDB與Vercel舉辦的Hackathon作品,很多高手都以Next.js參戰。
最後,如果您考慮使用EdgeDB作為Production Database的話,別忘了其也有提供雲端的EdgeDB Cloud服務。
註1:如果想學習Rust卻不知從何開始的朋友,我衷心推薦David的YouTube Rust教學及其於今年新出版的Learn Rust in a Month of Lunches書籍。
無間EdgeDB
初版完成於2024年1月,使用v4.x版本。在這之後EdgeDB一直持續改進,於v5版本添加了AI相關功能,讓其更容易與OpenAI、Mistral與Anthropic等工具整合。或許該是學習新功能,並編寫無間EdgeDB2
的時候了?
歡迎讓我知道您對本系列文或無間EdgeDB2
的想法:
select {
linkedin_profile:= "https://cv.ycwu.space",
github_username:= "@jrycw",
};
祝coding順利!