時
Full schema preview
# scalar types
scalar type DayOfWeek extending enum<Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday>;
scalar type FuzzyYear extending int64;
scalar type FuzzyMonth extending int64 {constraint expression on (__subject__ >=1 and __subject__ <=12)}
scalar type FuzzyDay extending int64 {constraint expression on (__subject__ >=1 and __subject__ <=31)}
scalar type FuzzyHour extending int64 {constraint expression on (__subject__ >=0 and __subject__ <=23)}
scalar type FuzzyMinute extending int64 {constraint expression on (__subject__ >=0 and __subject__ <=59)}
scalar type FuzzySecond extending int64 {constraint expression on (__subject__ >=0 and __subject__ <=59)}
# object types
type FuzzyTime {
fuzzy_year: FuzzyYear;
fuzzy_month: FuzzyMonth;
fuzzy_day: FuzzyDay;
fuzzy_hour: FuzzyHour;
fuzzy_minute: FuzzyMinute;
fuzzy_second: FuzzySecond;
fuzzy_dow: DayOfWeek;
fuzzy_fmt:= (
with Y:= <str>.fuzzy_year ?? "YYYY",
m:= <str>.fuzzy_month ?? "MM",
m:= m if len(m) > 1 else "0" ++ m,
d:= <str>.fuzzy_day ?? "DD",
d:= d if len(d) > 1 else "0" ++ d,
H:= <str>.fuzzy_hour ?? "HH24",
H:= H if len(H) > 1 else "0" ++ H,
M:= <str>.fuzzy_minute ?? "MI",
M:= M if len(M) > 1 else "0" ++ M,
S:= <str>.fuzzy_second ?? "SS",
S:= S if len(S) > 1 else "0" ++ S,
dow:= <str>.fuzzy_dow ?? "ID",
select Y ++ "/" ++ m ++ "/" ++ d ++ "_" ++
H ++ ":" ++ M ++ ":" ++ S ++ "_" ++
dow
);
trigger fuzzy_month_day_check after insert, update for each
when (exists __new__.fuzzy_month and exists __new__.fuzzy_day)
do (
assert_exists(
cal::to_local_date(__new__.fuzzy_year ?? 2002, __new__.fuzzy_month, __new__.fuzzy_day),
)
);
constraint exclusive on (.fuzzy_fmt);
}
Scalar types
DayOfWeek
DayOfWeek代表一星期內七天。
scalar type DayOfWeek extending enum<Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday>;
FuzzyYear
FuzzyYear直接extending int64。
FuzzyMonth
FuzzyMonth extending int64後,再加上一個constraint,限制其值只能為1~12。
scalar type FuzzyMonth extending int64 {
constraint expression on (__subject__ >=1 and __subject__ <=12)
}
FuzzyDay
FuzzyDay extending int64後,再加上一個constraint,限制其值只能為1~31。
scalar type FuzzyDay extending int64 {
constraint expression on (__subject__ >=1 and __subject__ <=31)
}
FuzzyHour
FuzzyHour extending int64後,再加上一個constraint,限制其值只能為0~23。
scalar type FuzzyHour extending int64 {
constraint expression on (__subject__ >=0 and __subject__ <=23)
}
FuzzyMinute
FuzzyMinute extending int64後,再加上一個constraint,限制其值只能為0~59。
scalar type FuzzyMinute extending int64 {
constraint expression on (__subject__ >=0 and __subject__ <=59)
}
FuzzySecond
FuzzySecond extending int64後,再加上一個constraint,限制其值只能為0~59。
scalar type FuzzySecond extending int64 {
constraint expression on (__subject__ >=0 and __subject__ <=59)
}
Object types
FuzzyTime
FuzzyTime除了包含前述七個scalar type為property外,還加了一個fuzzy_fmt property,一個trigger及一個constraint。
type FuzzyTime {
fuzzy_year: FuzzyYear;
fuzzy_month: FuzzyMonth;
fuzzy_day: FuzzyDay;
fuzzy_hour: FuzzyHour;
fuzzy_minute: FuzzyMinute;
fuzzy_second: FuzzySecond;
fuzzy_dow: DayOfWeek;
fuzzy_fmt:= (
with Y:= <str>.fuzzy_year ?? "YYYY",
m:= <str>.fuzzy_month ?? "MM",
m:= m if len(m) > 1 else "0" ++ m,
d:= <str>.fuzzy_day ?? "DD",
d:= d if len(d) > 1 else "0" ++ d,
H:= <str>.fuzzy_hour ?? "HH24",
H:= H if len(H) > 1 else "0" ++ H,
M:= <str>.fuzzy_minute ?? "MI",
M:= M if len(M) > 1 else "0" ++ M,
S:= <str>.fuzzy_second ?? "SS",
S:= S if len(S) > 1 else "0" ++ S,
dow:= <str>.fuzzy_dow ?? "ID",
select Y ++ "/" ++ m ++ "/" ++ d ++ "_" ++
H ++ ":" ++ M ++ ":" ++ S ++ "_" ++
dow
);
trigger fuzzy_month_day_check after insert, update for each
when (exists __new__.fuzzy_month and exists __new__.fuzzy_day)
do (
assert_exists(
cal::to_local_date(__new__.fuzzy_year ?? 2002, __new__.fuzzy_month, __new__.fuzzy_day),
)
);
constraint exclusive on (.fuzzy_fmt);
}
fuzzy_fmt
fuzzy_fmt為computed property,為一特殊的str格式來表達每個FuzzyTime object。其中??是指當該scalar type為空的set時(即<str>{}),所給予的預設值。
trigger
當同時給定fuzzy_month及fuzzy_day時,我們可以透過cal::to_local_date來驗證這樣的月份與日期,是否為一有效的組合。
逐步拆解各部份語法:
-
fuzzy_month_day_check為此trigger名字,可自行定義。after至for each中間,輸入想要trigger的類型。本例中是想要當對FuzzyTime進行insert及update時,才會觸發trigger。 -
when為選擇性條件,當其後expression為true時,才會觸發trigger。其中__new__是指我們想要insert或update的object。 -
do為這個trigger想要執行的內容。我們這裡使用assert_exists搭配cal::to_local_date來驗證給定的月份及日期組合是否合理。當沒有給定年份時,使用??語法指定為無間道主要劇情時間的2002年。由於我們的fuzzy_day已經被FuzzyDay限制在1~31之間,所以這個trigger可以幫我們去除掉2/30、2/31、4/31、6/31、9/31、11/31等不合理的時間,至於沒有給定年份的2/29是無法生成的(因為2002年不是閏年)。如果真的要生成2/29這麼特別的日子,需強制加上年份來鑒別其是否為一合理的時間。另外,當您使用略為超過合理時間的日期(如do ( assert_exists( cal::to_local_date(__new__.fuzzy_year ?? 2002, __new__.fuzzy_month, __new__.fuzzy_day), ) );4/31),cal::to_local_date報錯訊息會和一般情況不太一樣,會貼心地提示您這個日期剛好超出合理區間。
cal::to_local_date報錯訊息
constraint
針對fuzzy_fmt property加上exclusive後,可以確保當使用FuzzyTime時,不會生成一個以上可以表達同一模糊時間的FuzzyTime object。