Data values

View as Markdown

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:

  • Records method of applications returns properties of users.
  • Query method of databases returns the resulting rows from a query.
  • Read method of files takes a RecordWriter whose 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 type
int8(23) → 23
int16(512) → 512
int32(-802) → -802
int64(-1061274994) → -1061274994
uint(3095322305) → 3095322305
uint8(250) → 250
uint16(12000) → 12000
uint32(6038461) → 6038461
uint64(612) → 612
float32(51.0) → 51.0
1048553.0 → 1048553
decimal.MustInt(932811)932811
"932811"932811
[]byte("932811")932811
datetime time.Time
string2
float64
time.Date(2024, 4, 11, 16, 48, 26, 377105982, time.UTC)
"2024-04-11 15:59:05"
1712851145.0
date time.Time3
string2
time.Date(2024, 4, 11, 0, 0, 0, 0, time.UTC)
"2027-09-15"
time 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:

  • PreviewSendEvents method of applications takes extra event information.
  • SendEvents method of applications takes extra event information.
  • Upsert method of applications takes properties of a user.
  • Merge method of databases takes rows to be added or updated.
  • Write method of files takes a RecordReader whose Record method 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"}

  1. If the returned type is string, the only allowed values are "true" and "false"↩︎

  2. An empty string is interpreted as nil for nullable decimal, datetime, date, time, uuid, json, and ip types, as well as for nullable string types restricted to specific values that do not include the empty string. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  3. The time part is not relevant and is not considered. ↩︎

  4. The date part is not relevant and is not considered. ↩︎

  5. The value must be in the UUID textual representation "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" as defined by RFC 9562. ↩︎

  6. json.Value, string, and []byte values must contain valid JSON; the MarshalJSON method of the json.Marshaler interface must return valid JSON. ↩︎

  7. If the value is nil, the MarshalJSON method is still called, and it is expected to return the JSON null↩︎

  8. The string must represent a JSON Array. ↩︎

  9. The string must represent a JSON Object. ↩︎

  10. The location is always time.UTC↩︎

  11. The time part is always zero and the location is always time.UTC↩︎

  12. The date is always set to January 1, 1970, and the location is always time.UTC↩︎

  13. nil represents a nil value, not the JSON null. A JSON null is represented by json.Value("null")↩︎