Data values
When representing user and event data in a connector, these are mapped to specific Go types based on the data type. For example, in an export, a datetime value is represented in Go as time.Time, and a string value is represented as a string.
Import
During an import, connectors return data to import, such as user information. This data must use specific types according to the data type. Key scenarios for handling data in an application connector include:
Recordsmethod of applications returns properties of users.Querymethod of databases returns the resulting rows from a query.Readmethod of files takes aRecordWriterwhose methods return the read records.
Connectors can directly return values deserialized from JSON using the json.Unmarshal function, because the types returned by this function are supported.
The table below shows, for each data type, which Go type a connector can return. Note that in the "Examples" column, the symbol "→" shows how a value returned by a connector is interpreted.
| Krenalis type | Go type | Example |
|---|---|---|
boolean |
◦bool◦ string1 |
true"true" → true, "false" → false |
int(n)float(n)decimal(p,s)year |
◦int◦ int8◦ int16◦ int32◦ int64◦ uint◦ uint8◦ uint16◦ uint32◦ uint64◦ float32◦ float64◦ decimal.Decimal◦ string2◦ []byte |
12 // this and the following examples are for the int(n) data typeint8(23) → 23int16(512) → 512int32(-802) → -802int64(-1061274994) → -1061274994uint(3095322305) → 3095322305uint8(250) → 250uint16(12000) → 12000uint32(6038461) → 6038461uint64(612) → 612float32(51.0) → 51.01048553.0 → 1048553decimal.MustInt(932811) → 932811"932811" → 932811[]byte("932811") → 932811 |
datetime(See Time layouts) |
◦time.Time◦ string2◦ float64 |
time.Date(2024, 4, 11, 16, 48, 26, 377105982, time.UTC)"2024-04-11 15:59:05"1712851145.0 |
date(See Time layouts) |
◦time.Time3◦ string2 |
time.Date(2024, 4, 11, 0, 0, 0, 0, time.UTC)"2027-09-15" |
time(See Time layouts) |
◦time.Time4◦ string2◦ []byte |
time.Date(1970, 1, 1, 16, 38, 50, 204813055, time.UTC)"16:38:50.204813055"[]byte("23:09:26.047126396") → time.Date(1970, 1, 1, 23, 9, 26, 47126396, time.UTC) |
uuid5 |
◦string2◦ []byte |
"0296345b-23f6-48b4-9547-ff83fb637d0e"[]byte{211, 124, 89, 213, 136, 127, 68, 248, 143, 250, 126, 36, 49, 79, 71, 62} |
json6 |
◦json.Value◦ json.Marshaler7◦ string2◦ []byte |
json.Value(`{"p": 561}`)json.RawMessage(`{"p": 561}`) → json.Value(`{"p": 561}`)"[1, 2, 3]" → json.Value(`[1, 2, 3]`)[]byte(`{"points": 5}`) → json.Value(`{"points": 5}`) |
ip |
◦string2◦ net.IP◦ netip.Addr |
"192.168.1.1"net.ParseIP("192.168.1.1")netip.MustParseAddr("192.168.1.1") → "192.168.1.1" |
string |
◦string2◦ []byte |
"Emily Johnson"[]byte("Emily Johnson") → "Emily Johnson" |
array(T) |
◦[]any◦ []T◦ string8 |
[]any{618, 262, 791}[]int{19, -67, 8} → []any{19, -67, 8}"[19,-67,8]" → []any{19, -67, 8} |
object |
map[string]any |
map[string]any{"plan": "Premium"} |
map(T) |
◦map[string]any◦ map[string]T◦ string9 |
map[string]any{"1": "a", "2": "b", "others": "c"}map[string]int{"a": 1, "b": 2} → map[string]any{"a": 1, "b": 2}"{"a":1,"b":2}" → map[string]any{"a": 1, "b": 2} |
Time layouts
By default, values of type datetime, date, and time returned as string are parsed using the ISO 8601 format. The same applies to values of type time returned as []byte.
When registering the application connector, you can specify a different format if the values are not in ISO 8601, using any layout supported by the time.Parse function:
connectors.RegisterApplication(connectors.ApplicationSpec{
...
TimeLayouts: connectors.TimeLayouts{
DateTime: "2006-01-02T15:04:05.999Z",
Date: "2006-01-02",
Time: "15:04:05.999Z",
}
...
}, New)
Unix epoch
For the TimeLayouts.DateTime field of connectors.ApplicationSpec, you can also use special layout strings: "unix", "unixmilli", "unixmicro", or "unixnano". With these layouts, values returned as string or float64 are interpreted as the number of seconds, milliseconds, microseconds, or nanoseconds since the Unix epoch (January 1, 1970, 00:00:00 UTC).
Export
During an export, when a connector (whether application, database, or file) receives data to export, such as user information, it receives Go types specific to the data types. This involves methods such as:
PreviewSendEventsmethod of applications takes extra event information.SendEventsmethod of applications takes extra event information.Upsertmethod of applications takes properties of a user.Mergemethod of databases takes rows to be added or updated.Writemethod of files takes aRecordReaderwhoseRecordmethod returns the next record to write.
The following table shows, for each data type, what Go type a connector should expect when it receives a value. In the "Examples" column, the symbol "→" illustrates how a connector should interpret a received value.
| Krenalis type | Go type | Example |
|---|---|---|
string |
string |
"Emily Johnson" |
boolean |
bool |
true |
int(n) |
int |
-583 |
unsigned int(n) |
uint |
1499 |
float(n) |
float64 |
21.907305 |
decimal(p,s) |
decimal.Decimal |
decimal.MustParse("-123.45") |
datetime |
time.Time10 |
time.Date(2024, 4, 11, 16, 48, 26, 377105982, time.UTC) |
date |
time.Time11 |
time.Date(2024, 4, 11, 0, 0, 0, 0, time.UTC) |
time |
time.Time12 |
time.Date(1970, 1, 1, 16, 48, 26, 377105982, time.UTC) |
year |
int |
2024 |
uuid |
string |
"0296345b-23f6-48b4-9547-ff83fb637d0e" |
json |
json.Value13 |
json.Value(`{"p": 561}`) |
ip |
string |
"192.168.1.1" |
array(T) |
[]any |
[]any{618, 262, 791} |
object |
map[string]any |
map[string]any{"plan": "Premium"} |
map(T) |
map[string]any |
map[string]any{"1": "a", "2": "b", "others": "c"} |
-
If the returned type is
string, the only allowed values are"true"and"false". ↩︎ -
An empty string is interpreted as
nilfor nullabledecimal,datetime,date,time,uuid,json, andiptypes, as well as for nullablestringtypes restricted to specific values that do not include the empty string. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ -
The time part is not relevant and is not considered. ↩︎
-
The date part is not relevant and is not considered. ↩︎
-
The value must be in the UUID textual representation "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" as defined by RFC 9562. ↩︎
-
json.Value,string, and[]bytevalues must contain valid JSON; theMarshalJSONmethod of thejson.Marshalerinterface must return valid JSON. ↩︎ -
If the value is
nil, theMarshalJSONmethod is still called, and it is expected to return the JSONnull. ↩︎ -
The string must represent a JSON Array. ↩︎
-
The string must represent a JSON Object. ↩︎
-
The location is always
time.UTC. ↩︎ -
The time part is always zero and the location is always
time.UTC. ↩︎ -
The date is always set to January 1, 1970, and the location is always
time.UTC. ↩︎ -
nilrepresents anilvalue, not the JSONnull. A JSONnullis represented byjson.Value("null"). ↩︎