Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,4 @@ jobs:
uses: MobilityDB/MEOS-API/.github/actions/check-test-outcome@master
with:
log: test.log
min-tests: "118"
min-tests: "121"
6 changes: 3 additions & 3 deletions example_main_tbool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ func ExampleTBoolOut() {
func ExampleTBoolValueAtTimestamp() {
g_is := NewTBoolSeq("{FALSE@2022-10-01, FALSE@2022-10-02,TRUE@2022-10-03}")
ts, _ := time.Parse("2006-01-02", "2022-10-01")
res := TBoolValueAtTimestamp(g_is, ts)
fmt.Println(res)
res, ok, err := TBoolValueAtTimestamp(g_is, ts)
fmt.Println(res, ok, err)
// Output:
// false
// false true <nil>
}

func ExampleEverEqTBoolBool() {
Expand Down
6 changes: 3 additions & 3 deletions example_main_tfloat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ func ExampleTFloatValues() {
func ExampleTFloatValueAtTimestamp() {
tf_seq := TFloatIn("{1.2@2022-10-01, 2.3@2022-10-02,3.4@2022-10-03}", &TFloatSeq{})
ts, _ := time.Parse("2006-01-02", "2022-10-01")
res := TFloatValueAtTimestamp(tf_seq, ts)
fmt.Println(res)
res, ok, err := TFloatValueAtTimestamp(tf_seq, ts)
fmt.Println(res, ok, err)
// Output:
// 1.2
// 1.2 true <nil>
}
43 changes: 43 additions & 0 deletions example_value_absent_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package gomeos

// A temporal value holds nothing outside its own span, and MEOS says so by
// answering NULL. These examples pin what the accessors do with that answer:
// they report absence through a second result and leave the error free for a
// MEOS failure, and the nil handle it arrives as is a value the caller can test
// rather than something to dereference.

import (
"fmt"
"time"
)

func ExampleTBoolValueAtTimestamp_absent() {
tb := NewTBoolSeq("{FALSE@2022-10-01, FALSE@2022-10-02, TRUE@2022-10-03}")
outside, _ := time.Parse("2006-01-02", "2021-01-01")

value, ok, err := TBoolValueAtTimestamp(tb, outside)
fmt.Println(value, ok, err)
// Output:
// false false <nil>
}

func ExampleTFloatValueAtTimestamp_absent() {
tf := TFloatIn("{1.2@2022-10-01, 2.3@2022-10-02, 3.4@2022-10-03}", &TFloatSeq{})
outside, _ := time.Parse("2006-01-02", "2021-01-01")

value, ok, err := TFloatValueAtTimestamp(tf, outside)
fmt.Println(value, ok, err)
// Output:
// 0 false <nil>
}

func ExampleCreateTemporal_absent() {
tb := NewTBoolSeq("{FALSE@2022-10-01, TRUE@2022-10-03}")
outside, _ := time.Parse("2006-01-02", "2021-01-01")

// Restricting to a moment the value does not cover leaves nothing, which
// reaches Go as a nil Temporal rather than a handle onto nothing.
fmt.Println(TemporalAtTimestamptz(tb, outside) == nil)
// Output:
// true
}
7 changes: 7 additions & 0 deletions interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,14 @@ type NumSpan interface {
IsNumSpan() bool
}

// CreateTemporal wraps a MEOS temporal value in the Go type its temptype and
// subtype name. A MEOS entry answers NULL for an empty result — a restriction
// that selects nothing, for one — so a nil pointer is a value rather than a
// fault, and it arrives back as a nil Temporal for the caller to test.
func CreateTemporal(inner *C.Temporal) Temporal {
if inner == nil {
return nil
}
meosType := inner.temptype
subtype := inner.subtype
// meosType MeosType, subtype MeosTemporalSubtype
Expand Down
21 changes: 17 additions & 4 deletions main_tbool.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"fmt"
"time"
"unsafe"

"github.com/MobilityDB/GoMEOS/functions"
)

type TBoolInst struct {
Expand Down Expand Up @@ -198,10 +200,21 @@ func TBoolEndValue[TB TBool](tb TB) bool {
return bool(cValue)
}

// TBoolValueAtTimestamp Return the value of a temporal boolean at a timestamptz
func TBoolValueAtTimestamp[TB TBool](tb TB, ts time.Time) bool {
tboolinst, _ := TemporalToTBoolInst(TemporalAtTimestamptz(tb, ts))
return TBoolStartValue(tboolinst)
// TBoolValueAtTimestamp Return the value of a temporal boolean at a timestamptz.
// The second result reports whether the value holds anything at that moment;
// false leaves the first at its zero value. An error is reserved for a MEOS
// failure, which is a different thing from absence.
func TBoolValueAtTimestamp[TB TBool](tb TB, ts time.Time) (bool, bool, error) {
found, value, err := functions.TboolValueAtTimestamptz(
functions.TemporalFromPointer(unsafe.Pointer(tb.Inner())),
int64(DatetimeToTimestamptz(ts)), true)
if err != nil {
return false, false, err
}
if !found {
return false, false, nil
}
return value, true, nil
}

// AlwaysEqTBoolBool Return true if a temporal boolean is always equal to a boolean
Expand Down
21 changes: 17 additions & 4 deletions main_tfloat.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"fmt"
"time"
"unsafe"

"github.com/MobilityDB/GoMEOS/functions"
)

type TFloatInst struct {
Expand Down Expand Up @@ -368,10 +370,21 @@ func TFloatMinusValue[TF TFloat](tf TF, value float64) Temporal {
return CreateTemporal(c_tbools)
}

// TFloatValueAtTimestamp Return the value of a temporal float at a timestamptz
func TFloatValueAtTimestamp[TF TFloat](tf TF, ts time.Time) float64 {
tfloatinst, _ := TemporalToTFloatInst(TemporalAtTimestamptz(tf, ts))
return TFloatStartValue(tfloatinst)
// TFloatValueAtTimestamp Return the value of a temporal float at a timestamptz.
// The second result reports whether the value holds anything at that moment;
// false leaves the first at its zero value. An error is reserved for a MEOS
// failure, which is a different thing from absence.
func TFloatValueAtTimestamp[TF TFloat](tf TF, ts time.Time) (float64, bool, error) {
found, value, err := functions.TfloatValueAtTimestamptz(
functions.TemporalFromPointer(unsafe.Pointer(tf.Inner())),
int64(DatetimeToTimestamptz(ts)), true)
if err != nil {
return 0, false, err
}
if !found {
return 0, false, nil
}
return value, true, nil
}

// TFloatDerivative Return the derivative of a temporal number
Expand Down
21 changes: 17 additions & 4 deletions main_tint.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"fmt"
"time"
"unsafe"

"github.com/MobilityDB/GoMEOS/functions"
)

type TIntInst struct {
Expand Down Expand Up @@ -252,10 +254,21 @@ func TIntMaxValue[TB TInt](tb TB) int {
return int(cValue)
}

// TIntValueAtTimestamp Return the value of a temporal int at a timestamptz
func TIntValueAtTimestamp[TF TInt](tf TF, ts time.Time) int {
tintinst, _ := TemporalToTIntInst(TemporalAtTimestamptz(tf, ts))
return TIntStartValue(tintinst)
// TIntValueAtTimestamp Return the value of a temporal int at a timestamptz.
// The second result reports whether the value holds anything at that moment;
// false leaves the first at its zero value. An error is reserved for a MEOS
// failure, which is a different thing from absence.
func TIntValueAtTimestamp[TF TInt](tf TF, ts time.Time) (int, bool, error) {
found, value, err := functions.TintValueAtTimestamptz(
functions.TemporalFromPointer(unsafe.Pointer(tf.Inner())),
int64(DatetimeToTimestamptz(ts)), true)
if err != nil {
return 0, false, err
}
if !found {
return 0, false, nil
}
return value, true, nil
}

// AlwaysLtTIntInt Return true if a temporal integer is always less than an integer
Expand Down
20 changes: 16 additions & 4 deletions main_tpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"fmt"
"time"
"unsafe"

"github.com/MobilityDB/GoMEOS/functions"
)

// TPointOut Return a temporal geometry/geography point from its Well-Known Text (WKT) representation
Expand Down Expand Up @@ -66,10 +68,20 @@ func TPointEndValue[TP TPoint](tp TP) *Geom {
return &Geom{_inner: cValue}
}

// TPointValueAtTimestamp Return the value of a temporal point at a timestamptz
func TPointValueAtTimestamp[TP TPoint](tp TP, ts time.Time) *Geom {
tpointinst, _ := TemporalToGeomPointInst(TemporalAtTimestamptz(tp, ts))
return TPointStartValue(tpointinst)
// TPointValueAtTimestamp Return the value of a temporal point at a timestamptz.
// A temporal value that holds nothing at that moment yields an error rather than
// a value.
func TPointValueAtTimestamp[TP TPoint](tp TP, ts time.Time) (*Geom, bool, error) {
found, value, err := functions.TgeoValueAtTimestamptz(
functions.TemporalFromPointer(unsafe.Pointer(tp.Inner())),
int64(DatetimeToTimestamptz(ts)), true)
if err != nil {
return nil, false, err
}
if !found {
return nil, false, nil
}
return &Geom{_inner: (*C.GSERIALIZED)(value.Pointer())}, true, nil
}

// TPointValueSet Return the array of base values of a temporal geometry point
Expand Down
18 changes: 14 additions & 4 deletions main_ttext.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import "C"
import (
"time"
"unsafe"

"github.com/MobilityDB/GoMEOS/functions"
)

type TTextInst struct {
Expand Down Expand Up @@ -191,10 +193,18 @@ func TTextMaxValue[TT TText](tt TT) string {
return C.GoString(C.text_out(cValue))
}

// TTextValueAtTimestamp Return the value of a temporal text at a timestamptz
func TTextValueAtTimestamp[TT TText](tt TT, ts time.Time) string {
ttextinst, _ := TemporalToTTextInst(TemporalAtTimestamptz(tt, ts))
return TTextStartValue(ttextinst)
// TTextValueAtTimestamp Return the value of a temporal text at a timestamptz.
// The second result reports whether the value holds anything at that moment;
// false leaves the first at its zero value. An error is reserved for a MEOS
// failure, which is a different thing from absence.
func TTextValueAtTimestamp[TT TText](tt TT, ts time.Time) (string, bool, error) {
found, value, err := functions.TtextValueAtTimestamptz(
functions.TemporalFromPointer(unsafe.Pointer(tt.Inner())),
int64(DatetimeToTimestamptz(ts)), true)
if err != nil {
return "", false, err
}
return value, found, nil
}

// TTextUpper Return a temporal text transformed to uppercase
Expand Down
Loading