Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added ability for callbacks to have time.Time as arguments #604

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

sum12
Copy link

@sum12 sum12 commented Jul 10, 2018

go-sqlite3 can store time.Time values, and also has the fetaure to
register callback function to provide additionaly functions.

However these callback cannot take the mentioned time.Time columns as
input as there is no "dynamic-casting" of these values from TEXT to
time.Time.

With this patch that become possible letting user write custom functions
to do fancy filtering these time.Time columns

@sum12
Copy link
Author

sum12 commented Jul 10, 2018

If the features is acceptable then if required I will add tests

callback.go Outdated
var err error
c := (*C.char)(unsafe.Pointer(C.sqlite3_value_text(v)))
tv := C.GoString(c)
s := strings.TrimSuffix(tv, "Z")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sqlite3_value is coming from the database. So can I assume it will not have timezone in it ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://www.sqlite.org/lang_datefunc.html

SQLite does support time strings with time zone.

See section Time Strings

@mattn
Copy link
Owner

mattn commented Jul 10, 2018

please add test.

@sum12 sum12 force-pushed the timecallback branch 2 times, most recently from 2fbbed2 to ddb17e0 Compare July 11, 2018 09:21
@sum12
Copy link
Author

sum12 commented Jul 11, 2018

I have added tests. but I dont understand why the callbacks are failing for struct{}

@sum12 sum12 force-pushed the timecallback branch 2 times, most recently from 3d52bcb to cba271c Compare July 11, 2018 12:46
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.6%) to 57.348% when pulling 3d52bcb on sum12:timecallback into 3aefd9f on mattn:master.

@coveralls
Copy link

coveralls commented Jul 11, 2018

Coverage Status

Coverage decreased (-0.7%) to 57.657% when pulling 7791e15 on sum12:timecallback into 31f5bb8 on mattn:master.

@sum12
Copy link
Author

sum12 commented Jul 11, 2018

okay that should do it. Let me know what you think

@sum12
Copy link
Author

sum12 commented Aug 3, 2018

Any reviews on this one ?

@mattn
Copy link
Owner

mattn commented Aug 24, 2018

Seems good to me. cc @gjrtimmer

@sum12
Copy link
Author

sum12 commented Sep 11, 2018

thanks for fixing travis,
I have dropped the commit from the PR.

@sum12
Copy link
Author

sum12 commented Sep 16, 2018

@gjrtimmer do you have any more reviews?

@mattn
Copy link
Owner

mattn commented Mar 5, 2019

In recent changes, time.Time can be passed correctly. So IMO, this hack is not required. @sum12 Do you think?

@sum12
Copy link
Author

sum12 commented Mar 7, 2019

Could you please point me to the commit that added this functionality? I looked at callback.go and it doesnot have it.

Or may be you could help me convert this hack to something that is not a hack ?

@rittneje
Copy link
Collaborator

rittneje commented Mar 8, 2019

@sum12 I do have a few comments on your changes.

  1. Please use errors.New over fmt.Errorf if there are no format verbs (like %v).
  2. Please remove "an" from the error message.
  3. Please use C.GoStringN to account for embedded null bytes.
  4. If the input fails to parse to a time.Time, you aren't actually returning an error. Is that the intended behavior? It seems inconsistent to complain about it not being TEXT, but to be fine with it not being an actual time string.
  5. What if the input is an integer or float? It could be reasonable to interpret it as a Julian day or Unix timestamp. https://www.sqlite.org/lang_datefunc.html
  6. What about blobs? Elsewhere this library tries to treat blobs and strings equivalently. (See callbackArgString.)

go-sqlite3 can store time.Time values, and also has the fetaure to
register callback function to provide additionaly functions.

However these callback cannot take the mentioned time.Time columns as
input as there is no "dynamic-casting" of these values from TEXT to
time.Time.

With this patch that become possible letting user write custom functions
to do fancy filtering these time.Time columns
@sum12
Copy link
Author

sum12 commented Mar 17, 2019

@sum12 I do have a few comments on your changes.

1. Please use `errors.New` over `fmt.Errorf` if there are no format verbs (like `%v`).

done

2. Please remove "an" from the error message.

hrm, done.

3. Please use `C.GoStringN` to account for embedded null bytes.

this one was good for learning, thanks.

4. If the input fails to parse to a `time.Time`, you aren't actually returning an error. Is that the intended behavior? It seems inconsistent to complain about it not being TEXT, but to be fine with it not being an actual time string.

make sense, corrected.

5. What if the input is an integer or float? It could be reasonable to interpret it as a Julian day or Unix timestamp. https://www.sqlite.org/lang_datefunc.html

the library does not recognize the other formats, only SQLiteTimestampFormats are recognized.
I would love to add support for other formats, but in a different PR, after this.

6. What about blobs? Elsewhere this library tries to treat blobs and strings equivalently. (See `callbackArgString`.)

Accepted and corrected

Thanks for reviews, however I am still learning Go. Do you see anything else not in line ?
may be @mattn or @gjrtimmer ?

@mattn
Copy link
Owner

mattn commented Oct 25, 2021

@rittneje This is acceptable?

"unsafe"
)

var timetype = reflect.TypeOf(time.Now())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should just do reflect.TypeOf(time.Time{}). No need to take the hit of actually fetching the system times at startup.

@@ -243,10 +246,40 @@ func callbackArg(typ reflect.Type) (callbackArgConverter, error) {
c := callbackArgCast{callbackArgFloat64, typ}
return c.Run, nil
default:
return nil, fmt.Errorf("don't know how to convert to %s", typ)
switch typ {
case timetype:
Copy link
Collaborator

@rittneje rittneje Oct 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible that the callback arg is not time.Time directly, but rather a typedef on it (e.g., type Foo time.Time). If we want to support such things, then instead you want to check if time.Time is convertible to typ (using the ConvertibleTo method).

On that note, it looks like there are actually bugs in the existing logic on this point. For instance, if I have a callback that takes a string typedef (e.g., type Bar string), that will be allowed, because the kind of that type is still reflect.String. But later the call will lead to a runtime panic. https://play.golang.org/p/MI-324y6veS

Fixing that will require appropriate calls to Convert. For example: https://play.golang.org/p/k77Y82MDNeL

The problem is even more interesting for []byte (aka []uint8), because you cannot actually convert between []byte and []TypedefOnByte. That particular case should probably be fixed to just check if the arg kind is not string and []byte is convertible to the arg type (or the arg type is specifically []byte) rather than doing a kind-based check.

To be clear, I am not suggesting you fix the existing bugs in this PR (although that would be very much appreciated). Just that we should decide whether such typedefs ought to be rejected - in which case your new code is fine as-is - or accepted - in which case we need the extra calls to ConvertibleTo and Convert. @mattn What are your thoughts on this point?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants