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

[WIP] Using object literals to append rows to tables #42

Merged
merged 15 commits into from
Mar 7, 2014

Conversation

kneth
Copy link
Contributor

@kneth kneth commented Mar 3, 2014

Using NSArray and NSDictionary to append rows to tables will make objective c programs more readable.

The implementation is heavily inspired by our Python binding.

@ks @mekjaer @astigsen

@astigsen
Copy link
Contributor

astigsen commented Mar 4, 2014

Awesome, great start :-)

I look forward to support for dictionaries and objects as well ;-)

@astigsen
Copy link
Contributor

astigsen commented Mar 4, 2014

Shouldn't date columns expect NSDate objects as input? It would probably be pretty rare that users would want to save timestamps directly (as they are likely to only be able to get from NSDate objects anyways).

@astigsen
Copy link
Contributor

astigsen commented Mar 4, 2014

Same thing with binary. They should probably expect NSData objects as input:

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html

@kneth
Copy link
Contributor Author

kneth commented Mar 5, 2014

Our current interface is using time_t for dates but we could support both time_t and NSDate in appendRow. Similar for binary data.

size_t col_ndx = 0;
while (obj = [enumerator nextObject]) {
DataType type = table.get_column_type(col_ndx);
switch (type) {
Copy link
Contributor

Choose a reason for hiding this comment

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

To quote a conversation we had earlier with @kspangsege and @kneth :

The general paradigm I use is

switch(column_type)
{
case type_Int:
    ...
    goto ok;
case type_Float:
    ...
    goto ok;
case type_Double:
    ...
    goto ok;
case type_Bool:
case type_DateTime:
case type_String:
case type_Binary:
case type_Mixed:
case type_Table:
    RAISE_COLUMN_TYPE(column_ndx,
        "either int, float, or double");
    return Qnil;
}

RAISE_UNKNOWN_TIGHTDB_TYPE(); // returns from the function

ok:
    return result;

The effect is that the compiler will warn of any missing cases, and if
any new cases are added (to core) after the extension has been
compiled, the extension will duly fail.

Copy link
Contributor

Choose a reason for hiding this comment

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

If there is nothing common to do after "ok:", I would definitely 'return result' in the 'case' instead of 'goto ok'.

@oleks
Copy link
Contributor

oleks commented Mar 6, 2014

According to [1]: "When you’re writing code with Objective-C, exceptions are used solely for programmer errors, like out-of-bounds array access or invalid method arguments. These are the problems that you should find and fix during testing before you ship your app."

I would regard the programmer attempting to add a row of values where the values don't match the column types to be such a "programmer error", i.e. it should yield an exception. It seems to me that we haven't yet made a solid decision about what our strategy is wrt. to this sort of thing. I think we need to make that decision ASAP, so that we don't end up fundamentally changing our API in the coming months.

UPDATE: Just to clarify, appendRow will return false if the types are invalid, I would argue that it should yield an exception instead (and have no return value). I think in the java world, you'd otherwise also call the method "tryAppendRow", if it returned a boolean.

[1] https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ErrorHandling/ErrorHandling.html

@astigsen
Copy link
Contributor

astigsen commented Mar 6, 2014

Just to clarify, appendRow will return false if the types are invalid, I would argue that it should yield an exception instead (and have no return value)

Actually it would probably make sense for appendRow to return the index of the new row. That has turned out to be quite useful in the python binding.

For errors it should definitely raise exceptions.

@astigsen
Copy link
Contributor

astigsen commented Mar 6, 2014

+1

Would love to get support for dictionaries and objects as well, but I guess that can follow.

Any chance that we could get NSDate and NSData support included in this PR? It seem like it would be very easy to implement. Here is the date conversion code from Paul's example:

+ (NSDate*)dateFromTime:(time_t)timeValue
{
   if (timeValue > 0) {
      return [NSDate dateWithTimeIntervalSince1970:timeValue];
   } else {
      return nil;
   }
}

+ (time_t)timeValueFromDate:(NSDate*)date
{
   return [date timeIntervalSince1970];
}

kneth pushed a commit that referenced this pull request Mar 7, 2014
[WIP] Using object literals to append rows to tables
@kneth kneth merged commit 9dda075 into master Mar 7, 2014
jpsim added a commit that referenced this pull request Feb 6, 2017
I'm not sure why this fixes the crash.

Traceback (most recent call last):
  File "/Users/jp/Library/Application Support/Realm/rlm_lldb.py", line 226, in RLMResults_SummaryProvider
    if not is_results_evaluated(obj):
  File "/Users/jp/Library/Application Support/Realm/rlm_lldb.py", line 213, in is_results_evaluated
    mode_query_value = next(m for m in mode_type.enum_members if m.name == 'Query').GetValueAsUnsigned()
StopIteration
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00007fffcebe8ae6 libobjc.A.dylib`lookUpImpOrForward + 79
    frame #1: 0x00007fffcebe85d4 libobjc.A.dylib`_objc_msgSend_uncached + 68
    frame #2: Realm`-[RLMResults deleteObjectsFromRealm]::$_14::operator(this=0x00007fff5fbfb8c8)() const at RLMResults.mm:424
    frame #3: Realm`auto translateErrors<-[RLMResults deleteObjectsFromRealm]::$_14>(f=0x00007fff5fbfb8c8, aggregateMethod=0x0000000000000000) at RLMResults.mm:108
    frame #4: Realm`::-[RLMResults deleteObjectsFromRealm](self=0x000000010230bb10, _cmd="deleteObjectsFromRealm") at RLMResults.mm:417
    frame #5: Realm`::-[RLMRealm deleteObjects:](self=0x00006080000a2ca0, _cmd="deleteObjects:", array=(None[0])) at RLMRealm.mm:623
    frame #6: RealmSwift`Realm.delete<A where ...> (objects=<unavailable>, self=0x0000608000030040) -> () at Realm.swift:404
    frame #7: RealmSwift Tests`RealmTests.(realm=0x0000608000030040) -> ()).(closure #1) at RealmTests.swift:435
    frame #8: RealmSwift`Realm.write(block=0x0000000104a35270 RealmSwift Tests`RealmSwift_Tests.RealmTests.(testDeleteResults () -> ()).(closure #1) at RealmTests.swift:430, self=0x0000608000030040, $error=Error @ 0x00007fff5fbfbe40) throws -> ()) throws -> () at Realm.swift:124
    frame #9: RealmSwift Tests`RealmTests.testDeleteResults(self=0x0000608000089fb0) -> () at RealmTests.swift:437
    frame #10: RealmSwift Tests`@objc RealmTests.testDeleteResults() -> () at RealmTests.swift:0
    frame #11: 0x00007fffb9f733ec CoreFoundation`__invoking___ + 140
    frame #12: 0x00007fffb9f73271 CoreFoundation`-[NSInvocation invoke] + 289
    frame #13: 0x00000001000c847c XCTest`__24-[XCTestCase invokeTest]_block_invoke.234 + 50
    frame #14: 0x000000010010dcd6 XCTest`-[XCTMemoryChecker _assertInvalidObjectsDeallocatedAfterScope:] + 37
    frame #15: 0x00000001000c8040 XCTest`__24-[XCTestCase invokeTest]_block_invoke_2 + 665
    frame #16: 0x0000000100105916 XCTest`-[XCTestContext performInScope:] + 190
    frame #17: 0x00000001000c7d94 XCTest`-[XCTestCase invokeTest] + 254
    frame #18: RealmSwift Tests`TestCase.(self=0x0000608000089fb0) -> ()).(closure #1) at TestCase.swift:79
    frame #19: RealmSwift Tests`thunk at TestCase.swift:0
    frame #20: RealmSwift Tests`partial apply for thunk at TestCase.swift:0
    frame #21: 0x00000001021ef5c8 libswiftObjectiveC.dylib`ObjectiveC.autoreleasepool <A> (invoking : () throws -> A) throws -> A + 56
    frame #22: RealmSwift Tests`TestCase.invokeTest(self=0x0000608000089fb0) -> () at TestCase.swift:79
    frame #23: RealmSwift Tests`@objc TestCase.invokeTest() -> () at TestCase.swift:0
    frame #24: 0x00000001000c8803 XCTest`-[XCTestCase performTest:] + 565
    frame #25: 0x00000001000c5776 XCTest`__27-[XCTestSuite performTest:]_block_invoke + 300
    frame #26: 0x00000001000c5366 XCTest`-[XCTestSuite _performProtectedSectionForTest:testSection:] + 29
    frame #27: 0x00000001000c554c XCTest`-[XCTestSuite performTest:] + 214
    frame #28: 0x00000001000c5776 XCTest`__27-[XCTestSuite performTest:]_block_invoke + 300
    frame #29: 0x00000001000c5366 XCTest`-[XCTestSuite _performProtectedSectionForTest:testSection:] + 29
    frame #30: 0x00000001000c554c XCTest`-[XCTestSuite performTest:] + 214
    frame #31: 0x00000001000c5776 XCTest`__27-[XCTestSuite performTest:]_block_invoke + 300
    frame #32: 0x00000001000c5366 XCTest`-[XCTestSuite _performProtectedSectionForTest:testSection:] + 29
    frame #33: 0x00000001000c554c XCTest`-[XCTestSuite performTest:] + 214
    frame #34: 0x000000010011883c XCTest`__44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke + 40
    frame #35: 0x00000001000dbe0e XCTest`-[XCTestObservationCenter _observeTestExecutionForBlock:] + 587
    frame #36: 0x00000001001186da XCTest`-[XCTTestRunSession runTestsAndReturnError:] + 281
    frame #37: 0x00000001000b11fb XCTest`-[XCTestDriver runTestsAndReturnError:] + 254
    frame #38: 0x0000000100107fc9 XCTest`_XCTestMain + 773
    frame #39: 0x00007fffb9f957dc CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    frame #40: 0x00007fffb9f767e4 CoreFoundation`__CFRunLoopDoBlocks + 356
    frame #41: 0x00007fffb9f75f65 CoreFoundation`__CFRunLoopRun + 917
    frame #42: 0x00007fffb9f75974 CoreFoundation`CFRunLoopRunSpecific + 420
    frame #43: 0x00007fffb9501a5c HIToolbox`RunCurrentEventLoopInMode + 240
    frame #44: 0x00007fffb9501799 HIToolbox`ReceiveNextEventCommon + 184
    frame #45: 0x00007fffb95016c6 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 71
    frame #46: 0x00007fffb7aa75b4 AppKit`_DPSNextEvent + 1120
    frame #47: 0x00007fffb8221d6b AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 2789
    frame #48: 0x00007fffb7a9bf35 AppKit`-[NSApplication run] + 926
    frame #49: 0x00007fffb7a66850 AppKit`NSApplicationMain + 1237
    frame #50: TestHost`main(argc=5, argv=0x00007fff5fbfef58) at main.m:40
    frame #51: 0x00007fffcf4d9255 libdyld.dylib`start + 1
    frame #52: 0x00007fffcf4d9255 libdyld.dylib`start + 1
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants