iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
Software Development

一起看無間道學EdgeDB系列 第 18

[Day18] - 五幕:三年之後又三年

  • 分享至 

  • xImage
  •  

Full schema preview

本日所有schema搶先看

劇情提要

永仁與黃sir相約於天台交換情報,韓琛將於這星期進行毒品交易,地點未知。黃sir則說他費盡心力將永仁傷人的案子由坐牢改成看心理醫生,交待永仁要照做。永仁則抱怨自己被黃sir騙了,說好只當三年臥底,結果現在都快十年了,不知道何時才能恢復警察身份。十年間發生了太多事,永仁看著黃sir送的手錶,他有時候真的不知道該用什麼心態面對黃sir(詳情請見無間道Ⅱ及無間道Ⅲ)。

scene05
此劇照引用自IMDb-無間道

EdgeQL query

insert此場景時間2002年

insert FuzzyTime {fuzzy_year:= 2002};

建立alias及編寫測試aliasfunction

建立一個year_2002(2002年)的alias

alias year_2002:= assert_exists(assert_single((select FuzzyTime 
                                    filter .fuzzy_year = 2002 
                                    and .fuzzy_month ?= <FuzzyMonth>{}
                                    and .fuzzy_day ?= <FuzzyDay>{}
                                    and .fuzzy_hour ?= <FuzzyHour>{}
                                    and .fuzzy_minute ?= <FuzzyMinute>{}
                                    and .fuzzy_second ?= <FuzzySecond>{}   
                                    and .fuzzy_dow ?= <DayOfWeek>{}
                ))
);

新增test_scene05_alias()並更新test_alias()

function test_alias() -> bool
using (all({
        test_scene01_alias(),
        test_scene02_alias(),
        test_scene03_alias(),
        test_scene05_alias(),
    })
);

function test_scene05_alias() -> bool
using (all({
        (exists year_1994),
    })
);

執行end migration

did you create alias 'default::year_2002'? [y,n,l,c,b,s,q,?]
> y
did you create function 'default::test_scene05_alias'? [y,n,l,c,b,s,q,?]
> y
did you alter function 'default::test_alias'? [y,n,l,c,b,s,q,?]
> y 

測試test_alias()

# end migration needs to be applied before running this query
select test_alias();

update chen

這裡永仁連說了兩句經典台詞,讓我們把它們都加在classic_lines property中(留意這邊使用的語法是classic_lines := .classic_lines ++ array<str>)。

update chen 
set {
    classic_lines := .classic_lines ++ 
            ["你話三年。三年之後又三年,三年之後又三年!十年都嚟緊頭啦老細!",
             "收嗲啦!呢句嘢我聽咗九千幾次啦!"],
};

datetime的模糊加減法

假如我們想幫永仁算一下他所說的「三年之後又三年,三年之後又三年!十年都嚟緊頭啦」,大概是多久的話,可以使用cal::relative_duration()

我們假設永仁從1992年12月1日0時0分0秒,正式開始臥底工作。

首先我們需要將這個時間轉換為datetime型態。您可以選擇使用<datetime>casting或是使用to_datetime()來轉換。

初學EdgeDB的朋友可能會搞混這兩個方法。此時可以查看datetime文件,

通常沒有()的像是datetime或是cal::local_datetime,這代表是一種型態,可以於其後加上適當的strcasting

而像是有to開頭且有()to_datetime()或是cal::to_local_datetime(),則代表function,需要參考其所提供的各種簽名來使用。EdgeDB可以針對同一個function名定義多次,接收不同的參數,像是to_datetime()就提供六種可以呼叫的簽名,這種特性稱為function overloaded

下面四種query皆會產生同樣的結果:

select <datetime>"1992-12-01T00:00:00+08";
select to_datetime("1992-12-01T00:00:00+08");
select to_datetime(1992, 12, 1, 0, 0, 0, "Asia/hong_kong");
select to_datetime(
    <cal::local_datetime>"1992-12-01T00:00:00", 
    "Asia/hong_kong"
);
{<datetime>'1992-11-30T16:00:00Z'}

接下來利用cal::relative_durationcasting一個接近十年時間的str,假設為9年10個月。沒錯,cal::relative_duration可以接受像9 years 10 months這麼人性化的輸入!

select <cal::relative_duration>"9 years 10 months";
{<cal::relative_duration>'P9Y10M'}

接著我們將1992年12月1日0時0分0秒的datetime加上9年10個月的relative_duration

select <datetime>"1992-12-01T00:00:00+08" + 
       <cal::relative_duration>"9 years 10 months";
{<datetime>'2002-09-30T16:00:00Z'}

最後將結果的datetime型態轉變為local_datetime型態:

with t:=(select <datetime>"1992-12-01T00:00:00+08" + 
         <cal::relative_duration>"9 years 10 months")
select cal::to_local_datetime(t, "Asia/hong_kong");
{<cal::local_datetime>'2002-10-01T00:00:00'}

現在我們終於知道永仁與黃sir於本場景見面的時間,大概為2002年10月,這個計算大致符合劇中的時間線。

local_datetime的模糊加減法

datetime的計算看起來比較複雜,因為牽扯到timezone。如果您想要計算的是local_datetime的話,那麼可以輕鬆不少。

select <cal::local_datetime>"1992-12-01T00:00:00" + 
       <cal::relative_duration>"9 years 10 months";
{<cal::local_datetime>'2002-10-01T00:00:00'}

update wong

將黃sir的經典台詞指定給classic_lines property(留意這邊使用的是:=)。

update wong 
set {
    classic_lines := ["你25號生日嘛!25仔!"],
};

25仔在粵語中即為「反骨仔」或「臥底」之意。黃sir此舉乃是在嘲諷永仁。

local_date的模糊加減法

假設黃sir想幫永仁算一下,離永仁25號生日還有幾天,可以使用cal::local_date這麼算:

select <cal::local_date>"2002-10-25" - <cal::local_date>"2002-10-01";
{<cal::date_duration>'P24D'}

可以得知,大概還有24天(永仁於劇末的墓碑出生日期為1966年10月25日)。

insert此場景的Scene

insert Scene {
      title:= "三年之後又三年",
      detail:= "永仁與黃sir相約於天台交換情報,韓琛將於這星期進行毒品" ++
               "交易,地點未知。黃sir則說他費盡心力將永仁傷人的案子由" ++
               "坐牢改成看心理醫生,交待永仁要照做。永仁抱怨自己被黃sir" ++
               "騙了,說好只當三年臥底,結果現在都快十年了,不知道何時才" ++
               "能恢復警察身份。十年間發生了太多事,永仁看著黃sir送的手錶" ++
               ",他有時候真的不知道該用什麼心態面對黃sir(詳情請見無間道Ⅱ" ++
               "及無間道Ⅲ)。",
      who:= {wong, chen},
      `when`:= year_2002,
      where:= (insert Location {name:="天台"}),         
};

無間吹水

有一種說法是黃sir特別喜歡送人手錶。除了於天台送了永仁手錶外,無間道Ⅱ中Mary姐的手錶也是黃sir所送。所以當建明詢問Mary姐其所戴手錶是否為韓琛所送,她並沒有正面回應。

參考資料

無間EdgeDB五幕:三年之後又三年


上一篇
[Day17] - 四幕:被遺忘的時光
下一篇
[Day19] - 六幕:有內鬼終止交易
系列文
一起看無間道學EdgeDB30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言