時
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
。