weixin_39781363
weixin_39781363
2020-12-31 02:50

Create 4th Generator Template Directory for Supporting Realm

Hey Pascal!

Not sure if you'd be interested about this, but I wanted to extend your SwiftFHIR such that it would natively support Realm "out of the box." This is mostly because I was growing impatient hand-rolling my own Questionnaire models based on the FHIR DSTU2 spec. So I forked your fhir-parser project and kinda went to town. I created a RealmSwiftFHIR project which has the generated code in case you're curious about checking it out and running the tests and such. I am currently using this in a small iOS app that I'm developing at the University Health Network, and so far it seems to be working just peachy.

Anyways - long story short - I work (and have worked with for several years) with James Agnew, and he suggested I maybe clean up my original fork/branch a bit and re-submit it to you as a PR. If you're interested, well, here it is! If not, no harm no foul.

Cheers!

  • ryan.

-- old crappy notes This is a re-branching and more constructive commit of the original realm-spike branch, which blew away a huge portion of Pascal’s original project. Instead of basically re-inventing the wheel I created a 4th set of generator functionality, Swift3Realm, which can be merged into Pascal’s original project.

该提问来源于开源项目:smart-on-fhir/fhir-parser

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

15条回答

  • weixin_39613951 weixin_39613951 4月前

    godzilla-nope-response-meme

    点赞 评论 复制链接分享
  • weixin_39781363 weixin_39781363 4月前

    What, you don't like custard?

    点赞 评论 复制链接分享
  • weixin_39781363 weixin_39781363 4月前

    So is your thinking instead of bringing everything under one umbrella, that I just maintain my own RealmSwiftFHIR repo (more or less what I'm doing now), but change it such that it models your own Swift-FHIR wrt the parser?

    I like where you're going with this in the sense of other devs creating open "language packs" for the parser, which would be... groovy.

    rimshot

    点赞 评论 复制链接分享
  • weixin_39613951 weixin_39613951 4月前

    Yes exactly. You'll create your own base classes and templates (or re-use the ones in Swift-FHIR), and fhir-parser can be used as-is since it's no longer coming with language-specific files.

    点赞 评论 复制链接分享
  • weixin_39781363 weixin_39781363 4月前

    Cool beans man. Might as well shutter this PR this. Thanks for your help!

    Any specific attributions you'd like from my own repo, above and beyond anything which currently exists?

    点赞 评论 复制链接分享
  • weixin_39613951 weixin_39613951 4月前

    Depends. Do I get to choose the cake?

    点赞 评论 复制链接分享
  • weixin_39781363 weixin_39781363 4月前

    I'm feeling generous so why not! Otherwise you get to eat Red Bean Neapolitan with kale custard.

    点赞 评论 复制链接分享
  • weixin_39781363 weixin_39781363 4月前

    I suppose after that pre-amble I should actually outline what I've done! Ha!

    • Created a separate Swift3Realm folder which has the template and static class modifications for supporting realm. This entails the following:

    • The FHIRAbstrctBase class now inherits from Realm.Object, This is the absolute base thing which gets us the majority of the Realm magic

    • Realm doesn't support optional primitives outside of String, Date, and Data types. As a result, if we have an optional Int, then that must be wrapped in a RealmOptional<Int> type. The values of these types are get/set via .value. This is denoted in the requires_realm_optional property on the FHIRClassProperty class, and follows the same pattern as the other class_name_* functions in FHIRSpec. Each of the settings.py files have been updated with the requisite variables for fulfilling the fhirclass.py, fhirunittest.py, and fhirspec.py modifications (which are few).
    • Due to Realm not supporting UInt, these have been converted to Int
    • The various classes in the DateTime.swift are now inheriting from Realm.Object as well, in order to facilitate persistence
    • All arrays (such as Questionnaire.group) are now RealmList<T>s
    • JSON Serialization has been modified to take into account RealmList<T> and RealmOptional types
    • An additional field, pk, has been added to all Resource and Element types. This field defaults to a UUID string. When an instance is inflated from JSON, however, and that JSON contains a value for id, then the pk will be set to the same value as id. The pk field is marked as the realm PrimaryKey, and allows for Realm updates.
    • Contained resources don't play nicely with RealmList (you can't have polymorphic types in a RealmList). As a result, a new class called ContainedResource was created which contained the resourceType: String and json: Data?, which describes that contained resource. At run time, a lazy property, resource: FHIRAbstractBase?, will be inflated into the actual FHIR Resource.

    Off the top of my head I believe that's the majority of the changes. If you have questions feel free to ask and I'll reply.

    Cheers!

    点赞 评论 复制链接分享
  • weixin_39613951 weixin_39613951 4月前

    Oh sweet, thanks Ryan!

    What I wanted to do for a while is remove the language-specific stuff from fhir-parser itself and replace it with default settings/mappings, so the parser would truly be a parser only. I still hope to do that, in which case you'd just move the Swift3Realm folder to your library project. Just to have it noted, not sure when I get to that.

    Okay, on to the meaty bits: I have just given it a cursory overview and seen you needed to add two properties to the parser itself, primitives and realm_optionals. Handling optionals should be possible by using replacemap, e.g. `"Bool": "RealmOptional". Could you try that? I'd love to keep the parser "clean".

    What I just said may also apply to the primitives – how these are handled has changed quite a bit with the STU-3 version, the library has progressed since DSTU-2. I'm no longer using Swift-native classes for any property, everything is wrapped in FHIRString etc, which might be something for you to consider. I'm guessing the need for the primitive switch will go away with that. This move was needed because also primitive types can have extensions, which is not supported in the DSTU-2 version of the framework.

    Let me know what you think!

    点赞 评论 复制链接分享
  • weixin_39781363 weixin_39781363 4月前

    Hey man - sorry for the late reply. I submitted the PR then tossed out for the rest of the day. Glad to hear you're open to this whole Realm idear.

    In response to your points (which are grand): I'm definitely on board with trying to keep the parser as "clean" as possible. I felt ugly, like I'd been crying all night with a bowl of chicken wings in my lap and a fist clenching and handful of french fries while I massaged my face hole with grease kinda ugly, about adding those 2 additional fields to the settings. It didn't seem right. I'll strip those out like a Hannibal Lecter dinner party and see what I can do.

    As for DSTU-3 primitive support. That's interesting - I've admittedly not looked at the spec but figured it'd be relatively similar. The FHIRString approach should actually make the Realm stuff cleaner, like you said - I like the idea of being able to roll with official FHIR objects for primitives. One question I have is... have you done any work on the fhir-parser for DSTU-3 support yet? I'll have to give this one some thought on how to split it out. I'd ideally like to keep the DSTU-2 separate from the DSTU-3 generated stuff. How have you traditionally handled spec variations in the parser?

    Cheers!

    点赞 评论 复制链接分享
  • weixin_39613951 weixin_39613951 4月前

    Haha, I like the analogy (but now I'm hungry).

    Yes, versioning is handled like this: master branch is on the official latest FHIR version (i.e. DSTU-2 at the moment) and develop has been tracking STU-3. This goes for the SMART, FHIR and fhir-parser repositories. If you compare the branches you'll see that STU-3 has come a long way. This is not because the spec has changed, but because features and improvements have been done incrementally, and I didn't bother backporting everything.

    Alright, do the Lecter thing and check out the STU-3 branches, I'm guessing it will help in many ways (it did also make the FHIR client cleaner, I no longer need to check for primitive, as I mentioned).

    点赞 评论 复制链接分享
  • weixin_39781363 weixin_39781363 4月前

    Rock and roll man. I'll try and find a bit of time to prioritize this over the next few days. I'll hit you up with any questions I may have from my hunting and pecking. Thanks for all your feedback!

    点赞 评论 复制链接分享
  • weixin_39613951 weixin_39613951 4月前

    Hey Ryan! Sorry this comes in the midst of your work – I have gone ahead and removed all language-specific stuff from this repo (except for a tiny sample implementation that would work for Python).

    You can see in the Swift-FHIR repo what changes for you: just create a directory fhir-parser-resources in your client repo, copy your templates and stuff there and run the generator. You can re-use my setup in Swift-FHIR, with that and the updated README here you should be able to figure out how this works easily.

    Let me know how that works for you! 🤘🏼

    点赞 评论 复制链接分享
  • weixin_39781363 weixin_39781363 4月前

    Hey no worries dude. I finally set aside some time last night to work on the improvements we discussed earlier in this PR, and in doing so was attempting to revert any changes I originally made to the parser; trying to keep everything local to the language implementation.

    I'll take a look at this again on Thursday or so. I have next week off so I'm hoping to dedicate a bit more time to this.

    Thanks for the heads up! Much appreciated.

    点赞 评论 复制链接分享
  • weixin_39613951 weixin_39613951 4月前

    Sweet – what you want should definitely work. I'd suggest you copy over fhir-parser-resources from Swift-FHIR, then apply all the changes you made to the base classes and templates to those files. Then run vanilla generator and it should all work.

    点赞 评论 复制链接分享

相关推荐