<snusnu>
solnic: i've got 5 more minutes, thoughts? questions?
<solnic>
snusnu: yeah my first idea was to have rom relation wrapping axiom and using that inside graph but then I wasn't sure if we want to have relations with mappers inside the graph
<solnic>
so, you're saying we can build the graph with rom relations wrapping axiom and having injected mappers?
<solnic>
basically eliminating the need to have special nodes?
<solnic>
cause I'd love to do that
<snusnu>
solnic: i believe we can do that yes, but we need support from axiom
<snusnu>
solnic: as i said, the only reason for our current nodes is because Relation#join(other) doesn't support the join_definition
<solnic>
yeah
<solnic>
I thought we NEED nodes because they carry join info
<snusnu>
solnic: if axiom knew about the join definition, it could handle the jersey thing internally
<solnic>
but it doesn't do that yet
<snusnu>
right
<snusnu>
so i wonder
<solnic>
so...could we simplify this now by adding join definition to rom relation?
<snusnu>
*if* we're basically dropping lots of things already (which i btw like very much too) .. shouldn't we do it *right* this time?
<solnic>
basically replacing nodes with rom relations that are composed of axiom, mapper and join definition?
<solnic>
yes sir I want to do this right from the start
<snusnu>
solnic: then imo we should implement Axiom::Relation#join(other, join_definition)
<snusnu>
solnic: it will be needed anyway, to construct inner joins with the new sql generator
<solnic>
snusnu: ok
<solnic>
snusnu: my plan is to NOT bother with relationships now
<solnic>
so I could assume it'll be added later
<snusnu>
solnic: full ack
<solnic>
so I can nuke nodes
<snusnu>
lol
<solnic>
and build graph using rom relation
<solnic>
hey nuking code is fun
<snusnu>
i'd start building the graph with axiom relations
<solnic>
wait
<solnic>
so...what would rom relation do?
<snusnu>
actually, i wouldn't even implement the graph atm
<snusnu>
i would implement rom relation and the tuple level mapper
<solnic>
snusnu: well that's something I can finish TODAY :P
<snusnu>
then go for it! :)
<solnic>
ok but what will happen with graph
<solnic>
if we want to push more stuff to axiom
<solnic>
do we NEED graph?
<snusnu>
imo yes
<solnic>
apart from the fact that it's cool ;)
<solnic>
yes because?
<snusnu>
i.e. we need something that stores the information for constructing the join relations from relationship info
<mbj>
nuking code is really nice. Cannot participate in depth. Sorry.
<snusnu>
a graph with directed edges comes to mind
<solnic>
mbj: lol
<solnic>
mbj: go Markus, you have no time for irc now ;)
<mbj>
haha
<solnic>
snusnu: OK sounds right
<solnic>
snusnu: trying to wrap my head around this concept (again)
<snusnu>
solnic: when we define the "database" by constructing base relations (and virtual ones), we need a place to store the (FK) references … those are basically the join definitions we then store in graph edges that connect 2 nodes
<solnic>
so basically with a graph that uses axiom relations directly
<solnic>
we can use it to build rom relations
<solnic>
AND rom relations that get joined relations injected and proper mapper that knows how to load this stuff
<solnic>
s/get/receive/g
<snusnu>
right
<solnic>
oh you must've spent quite some time thinking about this stuff now haven't you? :D
<solnic>
but you know what, it seems SO MUCH SIMPLER now
<solnic>
so, from a user pov
<solnic>
you create relations using repository
<snusnu>
i think we'll have something like a Reference object that will have a name, and two sets of attributes (with link to the relation they're part of) that define the join_definiton .. think a sql FK constraints
<solnic>
and you can use them however you want by providing your own mappers (that's A very good start imho)
<snusnu>
yeah
<solnic>
no need for the graph until we start adding support for relationships
<snusnu>
absolutely
<solnic>
yeah, I think my mistake today was that I tried to figure out WHY would I need the graph now
<solnic>
and I kinda couldn't figure that out
<snusnu>
but imo we should tacke relationships differently this time
<solnic>
but now it makes sense :)
<snusnu>
we should start with FK reference objects
<mbj>
can we sync definitions somehow? relationship vs association? lets pick relationship, might be too close to relation?
<snusnu>
defined on the *database*
<snusnu>
i.e. on the graph
<snusnu>
of axiom relations
<snusnu>
those references are basically "one hop" relationships
<solnic>
snusnu: yes I like that
<snusnu>
either belongs_to or has_one
<solnic>
mbj: I think we settled on relationships but I think I'd prefer associations :)
<snusnu>
multi hops can easily be constructed by "chaining" single hops
<solnic>
snusnu: yeah if we could make it so that it's dead simple to join stuff by jumping through the nodes then we're done, mission accomplished
<snusnu>
and it makes sense, you walk a path along fk references
<mbj>
solnic: me too
<snusnu>
ok guys, gotta go, bbl
<mbj>
snusnu: ? s/relationship/association/ ?
<solnic>
yes, so basically those ref objects define A PATH in the graph
<solnic>
with details like how stuff gets joined (which fk are used)
<solnic>
snusnu: ok ttyl!
<snusnu>
think of a reference as exactly the info needed to define a sql fk constraint
<snusnu>
and a path is an array of those, with certain properties
<solnic>
yup
<solnic>
ok lemme nuke nodes first :D
<snusnu>
like, the source of the next reference, must be the target of the previous one, etc
<snusnu>
ok, go nuke codes, i'll let the doctor have a look at my eyes :)
snusnu has quit [Quit: Leaving.]
<solnic>
actually, I won't nuke it now
<solnic>
it can stay there for a reference until we get to it
<solnic>
yeah I can totally see how things would be simplified if we could inject some loading context object to axiom itself
kleech has joined #rom-rb
<mbj>
solnic: ree still supports 1.8.7 ?
<mbj>
solnic: So will ree receive updates bejond MRI 1.8 EOL`
<solnic>
kleech: so, basically we're taking a step back right now to simplify the code and start pushing some actual releases to rubygems
<kleech>
I thought with the rename it was a sure sign that a release was due shortly
<solnic>
kleech: we tackled too many problems at once in the prototype and now we're partially getting rid of the prototype and final implementation is in the works
<kleech>
I noticed quite a few of the repo's say they are spikes
<solnic>
damn, brb again
mbj_ has joined #rom-rb
<solnic>
kleech: ok back again
<solnic>
kleech: so, we're gonna release rom-relation soon but w/o relationship support and no built-in mappers yet
<solnic>
this is gonna be followed by rom-mapper release soon too
<solnic>
the thing is, we've got A TON of working code already, we just want to re-organize it a bit and improve
<kleech>
relationships as in has_many-esque assosiations?
<solnic>
but yeah, seems like everything is really shaping up nicely
<solnic>
kleech: yeah, no fancy dsl to define relationships yet
<kleech>
excellent news!
<solnic>
you'll be able to build joins however you like though
mbj has quit [Ping timeout: 248 seconds]
<solnic>
but you will have to load objects with your custom mappers
<solnic>
it's not bad actually, it'll be a good starting point
<kleech>
with the axiom SQL extension:?
<kleech>
^ I'm refering to assosiations
<solnic>
kleech: you'd just have to build a join yourself (as in, join two axiom relations together) and write a mapper that knows how to turn the response tuples into your objects
kapowaz has quit [Ping timeout: 301 seconds]
<kleech>
ah, understood
kapowaz has joined #rom-rb
<mbj_>
kapowaz: Or consume the tuples without mapping, for reports this is handy.
ChanServ has joined #rom-rb
kapowaz has joined #rom-rb
kapowaz has quit [Changing host]
<mbj_>
kleech: Or consume the tuples without mapping, for reports this is handy.
<mbj_>
sorry wrong nick
mbj_ has quit [Quit: leaving]
mbj has joined #rom-rb
<solnic>
mbj: yeah seems like freenode is flaky today
<solnic>
mbj: you know how to do update in axiom?
<solnic>
mbj: what I see now makes no sense at all
<solnic>
relation.delete(tuples).insert(tuples) <== this looks terribly wrong :D
<mbj>
solnic: This is the primitive yes.
<solnic>
delete those tuples then add them back? I mean, really? am I missing something?
<mbj>
solnic: dkubb implemented RA operations, and only ra operations. Once them are durable he added a more "nice" operation on top.
<mbj>
solnic: So I dont see a reason why we wont have an update soon ;)
<solnic>
mbj: yeah ok but how do I perform an update now?
<solnic>
this code obviously makes no sense
<mbj>
solnic: As you said ;)
<solnic>
dude, this code makes no sense
<mbj>
solnic: BTW in my production use I bypass the RA and axiom.
<solnic>
how did you do that in your adapters?
<mbj>
solnic: *for writes
<solnic>
ah shit
<mbj>
solnic: They dont support it. Because axiom does not supports it.
<solnic>
mbj: pretty sure it does, somehow
<solnic>
Dan said it does all the crud now
<mbj>
Okay my adapters *could* support delete / insert. But as this was not stable a the time I wrote them I did not implement this part.
<mbj>
u = d followed by i
<mbj>
But wee need it to be more efficient.
snusnu has joined #rom-rb
<mbj>
For that reason my rom-session think calls update with old and new tuple, so a clever driver could only updated changed fields.
<mbj>
I think this should bypass the adapters.
<mbj>
So the default adapter (in memory) should do update = delete / insert
<mbj>
The other adpaters will do it more "cleverly".
<mbj>
I think can would accept relation.update_tuple(old, new)
<mbj>
s/can/dan/
<mbj>
Or relation.update(old_tuples, new_tuples)
<solnic>
mbj: well, looks like current sql generator doesn't produce UPDATE yet
<solnic>
which is weird cause I could swear I had it working with engines
<mbj>
solnic: I never used the SQL part ;)
<mbj>
solnic: But I will soon.
<solnic>
oh wait
<solnic>
damn
<solnic>
that was with arel
<mbj>
haha
<mbj>
I did the failure to convince dan to rewrite axiom-sql-generator based on an sql ast.
<mbj>
So adding update statements will take longer ;)
<mbj>
But to use an intermediate sql ast is IMHO the correct approach. I had great success with axiom-arango-adapter and the aql gem.
<solnic>
I'm ok with that, it's just that I thought it already supports it
<solnic>
so it's a surprise for me
<snusnu>
solnic: the delete followed by update assumes that the deletion somehow uses only the key attributes to restrict the tuples to be deleted .. it then inserts those tuples again, but with changed non key attribute values
<solnic>
snusnu: and axiom will support that...later?
<snusnu>
solnic: but yeah, imo axiom should provide an update implemnetation
<solnic>
snusnu: I changed it
<snusnu>
solnic: tbh i dunno how axiom currently handles delete, it *is* fully supported tho
<solnic>
snusnu: because it was broken
<solnic>
will push in a minute
<snusnu>
cool
<mbj>
solnic: There is something nitpicking about current Relation#insert and Relation#delete!
<mbj>
solnic: They return a new relation with a specific object deleted/inserted.
<mbj>
solnic: So it some kind of "queues" up interactions.
<mbj>
solnic: That is by design and this is good IMHO.
<mbj>
solnic: We can easily write a gateway that has a "mutable" array of tuples inside
<mbj>
solnic: And actually performs that delete, so we dont queue up.
solnic has quit [Ping timeout: 240 seconds]
solnic has joined #rom-rb
<mbj>
solnic: you drop out a way to often these days... just like me
<mbj>
Keys are basically an optimized uniquenes criteria
<mbj>
A subset of the header.
<mbj>
If you dont set a key, the header is used as key. Wich is correct IMHO.
<solnic>
mbj: makes sense
<mbj>
yeah
<solnic>
mbj: ok this helps, I will add that to rom-relation
<mbj>
nice
<mbj>
BTW I really like loader/dumper name!
<mbj>
Mostly because they have equal length :D
<mbj>
And look very symetric in code that has symetric behavior
<mbj>
load(dump(object)) == object
<solnic>
yeah that's kinda cool
zaidan has joined #rom-rb
solnic has quit [*.net *.split]
solnic has joined #rom-rb
<snusnu>
solnic: imo ROM::Relation's crud methods should accept objects, not tuples
<snusnu>
solnic: btw, axiom currently performs deletion using Algebra::Difference which in turn yields left tuples unless right.include?(tuple) .. Set#include? is used here, so all tuples are checked for #eql? .. so, no key info is taken into account here
<solnic>
snusnu: yeah I know, just ported them from node code
<solnic>
snusnu: it's gonna look similar to what we had when it was a mapper wrapping relation
<mbj>
zaidan: lets handle that sorting / restricting on the client side
<mbj>
zaidan: So we can use "static" hosting via github pages.
<solnic>
snusnu: so basically now the relation will use its mapper to dump stuff and extract keys too
<solnic>
snusnu: for update and delete...can I use keys? if yes, how?
<snusnu>
solnic: as i said, it looks like Axiom::Relation#delete is implemented with difference and #insert with union, which both work on top of object (tuple) equality .. i don't see how axiom supports using keys for #delete just yet .. obviously #update is not implemented at all atm
<solnic>
snusnu: I need to talk to Dan about this
<solnic>
seems like we're missing some crucial stuff here
pdswan has joined #rom-rb
<snusnu>
solnic: yeah, i think i can see how the current implementation takes care of the basic RA ops (which assume the whole header is the key, therefore object equality is (was) the right choice)
<mbj>
solnic: #delete is basically a filter, and #insert an append
<mbj>
solnic: We can have a #delete_key that filters by key
<snusnu>
solnic: now that axiom knows about keys too, i think these need to be reflected in #delete and #update
<solnic>
snusnu: that's what I want to do
<mbj>
solnic: I think it should be enough to use a tuple with only key fields in #delete
<snusnu>
solnic: yeah, i was about to say that #delete and #update can be implemented by restricting beforehand, based on keys, but i dunno if dkubb had different plans (primitives)
<mbj>
I remember somehow he planned it like this.
<solnic>
that was my thinking too
<snusnu>
solnic: yeah, for #update and #delete, only the keys need to be taken into account, to filter the relation
<solnic>
ok so once you have the relation for update, what do you do next? :)
<mbj>
snusnu: Remember for differencial updates we need the full old tuple to generate a minimum update statement. For this reason my mappers bypassed the RA for writes.
<mbj>
snusnu: *when keys where in use to identifiy affected tuple
<snusnu>
imo it works like this: you get an array of *objects* (not tuples), dump those to tuples that only contain key attribute values, and delete those from the relation, then you just insert the "full" tuples .. so imo a signature that accepts both old and new tuples for #update is not necessary
<mbj>
snusnu: It is for minimum differencial updates!
<solnic>
snusnu: ino it's tmp
<solnic>
just wanted to make the spec pass
<solnic>
for a good start
<solnic>
update should accept attributes for update though
<solnic>
session will provide those
<solnic>
if you make it accept only an object
<snusnu>
mbj: so, what i'm saying is, when i use ROM::Relation#update (as a user), i don't want to pass in old and new tuples, i want to pass in only the updated *objects*
<solnic>
then it'd have to get all attributes from that object
<mbj>
No problem rom-session will provide access to the old tuple
<solnic>
hmm ok
<mbj>
snusnu: I was on the wrong layer, sorry.
<snusnu>
what if i don't want to use rom-session?
<mbj>
You dont get a chance for differencial updates.
<mbj>
At least with this public api.
<mbj>
Lets define a minimum public api
<mbj>
Implement it, and expand.
<mbj>
I'm okay with full updates.
<snusnu>
of course not (differential updates)
<mbj>
*for initial versions
pdswan_ has joined #rom-rb
<snusnu>
i want to be able to just say: ROM::Relation.new(relation, mapper).update( [ Person.new(id: 1, name: 'John') ] )
<snusnu>
if id: 1 was already present, it will simply update the name
<mbj>
snusnu: And if it was not already present it would insert? so lets call it #sync ;)
<snusnu>
imo no, not on this level
<solnic>
snusnu: not sure if that's a good idea
<snusnu>
solnic: what specifically?
<solnic>
passing objects in
<solnic>
for update
<snusnu>
huh what?
<solnic>
instead of changed attributes
<solnic>
not sure
<solnic>
just thinking :)
zaidan_ has joined #rom-rb
pdswan has quit [Ping timeout: 256 seconds]
zaidan has quit [Ping timeout: 256 seconds]
pdswan_ is now known as pdswan
<snusnu>
i will typically send a person instance from an edit form, the processing on the server will make sure that my action sees a Person instance … if i now want to explicitly *update* that person, ROM::Relation#update should fail if there is no person with the given key
<snusnu>
some other layer (session) might add more trickery
<zaidan_>
mbj: will rewrite that tomorrow
<mbj>
snusnu: okay for me
<solnic>
snusnu: yeah well session can pass in objects down to relation when it sees they changed but then relation needs to know WHAT changed
<snusnu>
imo for all ROM::Relation crud ops, we should accept just the same stuff as axiom expects for those ops .. only as objects, not tuples
<snusnu>
session keeps dumps of the involved objects, no? so it can compare those?
<mbj>
snusnu: Session, in current implementation, nows about all dumps of all loaded objects.
<mbj>
dumps == tuple
<mbj>
snusnu: This allows to do external dirty tracking.
<solnic>
snusnu: session knows everything :P but relation doesn't
<snusnu>
imo axiom #delete (i.e. Algebra::Difference) should be rewritten to take keys into account, once that's done, #update is easy to implement (#delete using keys, followed by #insert .. or translated to sql update statement)
<solnic>
but in order to generate an optimized update statement you need to know WHAT changed
<snusnu>
i'd love to expose the *same* interface for Axiom and ROM relations, with the *only* difference being that rom relation accepts objects, not tuples
<mbj>
snusnu: IMHO axiom should implement #update for itself this way.
<solnic>
session knows that and by passing only the object to relation you loose this info
<mbj>
snusnu: Allowing adapters to do real updates without *magically* collapsing delete followed by insert.
<snusnu>
mbj: yeah, axiom should implement #update this way
<solnic>
yeah delete-followed-by-insert is weird
<snusnu>
solnic: i'm not sure if we need to support optimized (minimal) update statements without using the session
pdswan has quit [Ping timeout: 264 seconds]
<snusnu>
solnic: after alll, without session, we explicitly don't provide dirty tracking
<snusnu>
solnic: which is needed for minimal updates anyway
<solnic>
snusnu: we don't but when we DO want to support it with session, how would we add that to rom-relation?
zaidan_ has quit [Read error: Connection reset by peer]
kapowaz has quit [Ping timeout: 264 seconds]
<mbj>
rom-relation can be summarized as?
<mbj>
(dont say relation-graph)
<snusnu>
imo its sole purpose is to be able to iterate over and write *objects*
<snusnu>
it has *nothing* to do with the graph
<solnic>
yeah graph will just help us with relationship support
<mbj>
sync
<snusnu>
so, i guess i'm maybe not against some *other* api that accepts old and new objects for (minimal) update, but i'd like to have #update accept just what axiom's #update accepts, only in object form ..
<snusnu>
i guess it can be done so that the only difference between axiom and rom relations is the fact that one exposes and accepts tuples (axiom) and the other objects (rom)
<snusnu>
our mapper will be able to infer (dump) tuples from objects anyways
<snusnu>
and vice versa
<solnic>
yup that's how it worked with mappers wrapping relations
<snusnu>
yeah, what we now call mapper, previously was attribute set
<snusnu>
and that makes more sense imo
<snusnu>
i mean, to call it mapper
<snusnu>
:)
<solnic>
yeah totally
<solnic>
snusnu: I wonder though. what's the value of #update accepting an object and going with a full-blown update statement?
<solnic>
you almost never want that
<elskwid>
ping solnic
<solnic>
pong elskwid
<elskwid>
solnic: That little leftover in the spec was to remind you and I that they aren't quite done for ModuleBuilder.
<elskwid>
solnic: My brain isn't warped enough yet to see the best way to test that class in your rspec style.
<elskwid>
:)
<snusnu>
solnic: i guess that boils down to the question wether you want to use rom with or without a session, you probably never want to do the former, but if you want to, you probably wouldn't expect it to do any dirty tracking, because that's session's job, and you've opted out of that
<snusnu>
s/former/latter
<solnic>
snusnu: weeeeeelllll but it COULD expose an interface for partial updates, no?
<solnic>
that interface could be then used by the session
<snusnu>
solnic: right, that's what i said, i'd accept such an additional interface, but i'd want to have the "classic" api too
<solnic>
snusnu: sure
<solnic>
elskwid: lemme see
<solnic>
elskwid: module builder is our internal private API rite?
<elskwid>
solnic: I have some more time this morning, and really, those are the only specs that need attending to.
<elskwid>
solnic: It is.
<solnic>
elskwid: so, can we test it implicitly?
<elskwid>
solnic: I was working to get it covered like the rest.
<solnic>
cause we should
<elskwid>
solnic: There is an integration test that shows me it's working
<elskwid>
solnic: I just didn't want to drop this pull request on you and leave a bunch of other stuff to do. heh.
<solnic>
elskwid: I can clean this up a bit no worries
<solnic>
elskwid: don't want you to burn out because of my nitpicking :D
<elskwid>
solnic: I'd love to get it merged but I'd also love to learn more. No burn out!
<elskwid>
solnic: My goal is to continue to contribute so it's good for me to get how you do this stuff.
<solnic>
elskwid: ok :)
<elskwid>
solnic: We could try to do some of it in realtime if you think it would go faster (I certainly do)
<solnic>
elskwid: I'd say we should test this module implicitly, it's an internal private object
<elskwid>
solnic: Is there an example in this codebase of that being done?
<solnic>
elskwid: well, just add a unit spec for Virtus.module
<solnic>
checking whatever it needs to check
<solnic>
and remove tests for module builder
<solnic>
the fact we use some builder under the hood is rather an implementation detail here
<elskwid>
I agree with that
<elskwid>
The other coverage is pretty intimidating though. ha ha
<elskwid>
solnic: p.s. Never worry about nitpicking my code. I love it.
<solnic>
yeah I dislike the mount of specs in virtus
<solnic>
there's a lot of stuff that shouldn't be covered directly
<solnic>
it's the result of using heckle and the mutant, both tools required that style
<solnic>
I disagree with it and luckily mbj is working to make mutant handle that better
<solnic>
s/the mutant/then mutant/
<elskwid>
solnic: I figured as much.
<solnic>
elskwid: ok so lemme nitpick a little bit :)
<elskwid>
solnic: GREAT!
<elskwid>
solnic: Then I can wrap this thing up. I'll add the tests for Virtus.module (thought I had) and will do a little rebase+squash and we'll be good to go.
<elskwid>
solnic: I had an idea for my next addition here so I can stay busy.
<snusnu>
mbj: btw, does anima know how to dump the attribute hash recursively?
<snusnu>
solnic: same question goes for virtus
kleech has quit [Remote host closed the connection]
<elskwid>
solnic: One note: I recently started using emacs fulltime so I definitely need someone checking things! (My poor brain...)
<solnic>
elskwid: vim user here
<solnic>
elskwid: also, I added some comments
<elskwid>
solnic: The biggest challenge I've had so far, realizing that I was a slave to tree-view to help keep a project in my head.
<elskwid>
Wow.
<solnic>
if you could clean this up and replace explicit specs for module builder with unit tests for Virtus.module then we're done :)
<elskwid>
solnic: You got it! It was fun working on this yesterday. I basically swapped Virtus for client work. ha ha
<solnic>
elskwid: sweet :)
<elskwid>
Also, I'm happy with the name change. I like it a lot.
<elskwid>
Get rid of that baggage!
<solnic>
yeah it gave us a nice energy boost
<elskwid>
solnic: Good nitpicks.
<solnic>
yeah I used to think nitpicking is annoying
<solnic>
but now I don't :P
<solnic>
those details help you in keeping the code clean and consistent, it's much easier to read code that's written in the same style
<solnic>
and as we know you can write ruby in various ways
<elskwid>
solnic: For me, I just need to get a feel for the way you like it written in your project. It's funny, several of these things were the first way I did them then changed them. *sigh*
<elskwid>
I'm on it.
<solnic>
cool
<solnic>
brb gotta grab sth to eat
kleech has joined #rom-rb
<mbj>
snusnu: no, do this via the mapper.
<mbj>
snusnu: s/mapper/ducktrap/ ;)
<mbj>
busy, ordering a notebook ;)
<snusnu>
mbj: i don't get what you're saying … if we want our new mapper to be able to load/dump rich (i.e. composed) domain objects, surely we need something that knows how to dump a (composed) anima/virtus object to a hash and vice versa
<mbj>
snusnu: nope
<solnic>
snusnu: I don't think virtus does that
<mbj>
snusnu: mom, let me order that thing
<solnic>
snusnu: it can build objects from nested hashes
<mbj>
snusnu: dumping an embedded object must be specified, anima/virtus should not know anything about dumping itself.
<snusnu>
solnic: right, and can it dump nested hashes from composed objects?
<solnic>
but there are limitations when it comes to dumping them back to hashes
<mbj>
snusnu: The ducktrap/mapper walks a domain object structure dumping to a tuple
<mbj>
snusnu: I created ducktrap for exaclty that "created hested stuff out of domain objects" and transform back thing...
<mbj>
snusnu: I have really deep document structures in my nosql dbs, works great.
<mbj>
snusnu: And the domain object layer is allowed to look differend but similar as you wish, thx to ducktrap...
<snusnu>
ok, so once axiom supports (un)group, we'll definitely need something that knows how to dump/load the nested hash (that is a result from group)
<solnic>
snusnu: it's easy when you know what to dump
<solnic>
it's tricky when you don't because of recursive refs
<elskwid>
solnic: Got a second to discuss the Configuration.new.call syntax?
<snusnu>
in a future scenario, when person has many tasks, and axiom loads a relation that includes a person's tasks, it will (thx to #group) return: { id: 1, name: 'John', tasks: [ { id: 1, description: 'foo'}, … ] }
<solnic>
elskwid: yeah I'm around, I may respond with a small delay :>)
<snusnu>
our mapper must know how to map that into objects
<solnic>
snusnu: virtus would load it automatically
<solnic>
but dumping is much more difficult
<snusnu>
similarly, if we receive Person.new(id: 1, name: 'John', tasks: [ Task.new(id: 1, description: 'foo'), … ]) … we need to dump that somehow
<snusnu>
solnic: yeah, i see how recursive refs might be tricky here
<snusnu>
i'm not saying anima/virtus must do it, i'm saying *something* must do it
<snusnu>
mbj, solnic: imo we should finally all get an equal understanding about what ducktrap can and more importantly *should* do
<snusnu>
so much of the stuff we need overlaps with ducktrap
<snusnu>
but imo ducktrap is best used as the outer fence for rejecting malformed parameters
<snusnu>
and then dumping an object to an arbitrary structure used in the final response data structure
djsell has joined #rom-rb
<mbj>
sorry, busy
<snusnu>
somehow it feels like we should use a trimmed down ducktrap (without error reporting stuff) as our mapper .. specifying the dump part, and therefore get the load for free
<solnic>
snusnu: yes we briefly talked about this with mbj already
<mbj>
snusnu: Why do you fear the error reporting?
<mbj>
snusnu: Overhead is 10%
<mbj>
snusnu: Also we could use it now, and make error reporting optional in future.
<mbj>
snusnu: Or rerun a failed ducktrap with transformation tracking after error.
<mbj>
snusnu: No reason to avoid ducktrap *now*
<mbj>
IMHO
<solnic>
from my pov getting relations working with full CRUD is the most important thing to worry about
<elskwid>
solnic: What about Configuration.build that just uses new.call(block) underneath?
<snusnu>
mbj: the reason i "fear" it (which i don't btw) is that i think that once a request hits DB interaction, it should be guaranteed to be valid anyway. obviously, on the way out, we should assume that everything is valid anyway
<solnic>
elskwid: yes even better
<elskwid>
solnic: We need to have that #call so we can get access to the configuration with a block from the Virtus.config
<elskwid>
solnic: Excellent!
<solnic>
elskwid: ah rite :)
<elskwid>
solnic: I'd like to see that in Coercible too (I could have used it)
<snusnu>
mbj: so if we were to write our own mapper, we definitely wouldn't implement any validation concerns there
<elskwid>
I know mutation is OUT but the configuration is really just state for the lib.
* elskwid
ducks
djsell has quit [Quit: Leaving.]
<mbj>
snusnu: ducktrap is not validating
<snusnu>
now *that's* nitpicking
<snusnu>
;)
<snusnu>
on terminology
<mbj>
snusnu: It does not trust the input and does not call blindly #map and friends on the input.
<snusnu>
call it sanitizing, whatever
<mbj>
snusnu: haha
<snusnu>
see, here's the point, it does *not* trust the input … at this point we DO TRUST
<mbj>
snusnu: But we can easily compile the transformation to a tracking free transformation
<mbj>
snusnu: That is the idea of a declarative inverisble transformation...
<snusnu>
i know that, but it's a matter of responsibilities and not programming defensively .. once an object reaches ROM::Relation API, it *must* be sanitized/validated/whateverd
<mbj>
snusnu: You cannot imagine how much stuff slipped through before I had ducktrap.
<mbj>
snusnu: Sometimes I changed the mapping in a way I thought db side data will still fit in
<mbj>
snusnu: But it wasnt ;)
<snusnu>
mbj: yeah, and as i said, i love ducktrap especially for its error reporting, all i'm saying is that if we use it as the mapper to inject into rom relations, it should *not* do all its error checking *again*
kleech has quit [Remote host closed the connection]
<mbj>
snusnu: We have an open stack with small interfaces, feel free to write your own. (no joke, and I'd love to see another approach)
<snusnu>
mbj: sorry, i guess we're not synced yet :)
<mbj>
snusnu: Ducktrap.build { dsl; dsl }.trust
<snusnu>
now we're getting there …
<snusnu>
hehe
<mbj>
snusnu: trust would return a #call able object that does not have error tracking....
<mbj>
snusnu: I dont trust my db, or the brains that dump data inside (especially nosql)
<snusnu>
there's other conceptual overlap tho .. when specifying a mapper, we actually wouldn't want to use ducktrap'ish dsl .. we'd still want to use an API close to what we currently have .. ducktraps can be built based on that
<mbj>
snusnu: I like the OO layer of ducktrap more than the dsl.
<snusnu>
see, you have to have more trust, i don't want to go through sanitizing/validating/whatevering data coming out of my db
<mbj>
snusnu: So dont use that feature?
<solnic>
yes this is crazy
<snusnu>
lol, that's what i'm saying, *if* we use ducktrap there, we should use a trimmed down code path
<mbj>
snusnu: yeah
<mbj>
snusnu: But we can use ducktrap *now*
<mbj>
get a release out
<mbj>
And reduce code path later...
<mbj>
interface will be the same
<snusnu>
of course
<mbj>
sorry, I'm angry because they payment systems *suck*
<snusnu>
hah
<solnic>
me no likey ducktrap's dsl
<solnic>
like, at all
<snusnu>
solnic: yeah, the dsl isn't perfect atm, the concept's great tho
<solnic>
yeah we need that
<solnic>
for the mapper
<mbj>
I'd be very happy to have a simpler dsl for mapper
<mbj>
for common stuff
<snusnu>
but it somehow feels a bit weird that we can use it on the outer fence, and then again at the innermost point .. now it isn't weird per se, but it is weird as long as i can't clean up the responsibilities it needs to assume, in my head
<mbj>
But when I have to go crazy again I'd love to be able to plug bigger ducktraps....
<mbj>
snusnu: Object oriented design, at all zoom levels it looks the same!
<mbj>
snusnu: I like code reuse!
<snusnu>
who doesn't
<snusnu>
:)
<mbj>
It is a quote dkubb posted once, object oriented design is a fractal.
<snusnu>
what i'm concerned with, is that we *must* have a very clear picture of its responsibilities at each layer
<mbj>
I have it. You too? :D
<snusnu>
obviously not :)
<mbj>
The problem: We must have the *same* picture ;)
<snusnu>
right :)
<mbj>
That is so stupid, I want to order my notebook *NOW* not tomorrow, not the next week NOW.
<mbj>
So I have access to a credit card with high enoug limit...
<mbj>
But not my motherfucking name printed on it.
<mbj>
And they dont accept it as payment vektor.
<snusnu>
so, at the innermost point (i.e. the mapper we inject into rom relations) we need to construct a non-error checking ducktrap, based on information gathered in a mapper dsl similar to our current mapper dsl
<snusnu>
and we (as in the rom team) don't care how people use ducktrap on the outer fence (we do have opinions, but they're out of rom scope)
<mbj>
And I cannot order under the name of my father, because I could not reduce VAT in this case...
<mbj>
And I decided my own card should have a very low limit. Because I dislike credit cards....
<mbj>
Dont have a paypal account...
<mbj>
And the fucking bank did not finished their fucking transaction.
<mbj>
Enough non "usable" money in transit...
<mbj>
Sorry, I hate this. We live in 2013, arent we?
<mbj>
</done>
<solnic>
kinda
<snusnu>
lol
<mbj>
At some day I'll do a bank, one rule: We book fast and do nothing else with the money.
<mbj>
0.25€ per transaction. Fixed fee.
<solnic>
mbj: good luck with that ;)
<mbj>
solnic: hehe
<snusnu>
so, we need to construct a ducktrap based on information like: map :foo, Integer, :to => bar
<mbj>
snusnu: We'll have a mapper specfic dsl that calls oo interface on ducktrap.
<mbj>
have to run, bb in 20min
mbj has quit [Quit: leaving]
<snusnu>
mbj: yeah
<solnic>
snusnu: btw I forgot to mention - I'm not going to write separate specs for all the stuff we have, I will only write specs for public interfaces (this excludes "private" objects if you know what I mean)
<snusnu>
solnic: i very much welcome that
<solnic>
I really hate the amount of specs we have, TON of duplication there
<snusnu>
full ack
<solnic>
mutation tools required that, fine, but it's silly
<solnic>
now we have master mbj who can fix the mutation tool :)
<snusnu>
exactly
<snusnu>
:)
<solnic>
so that's one rule, another rule - no specs for attr readers (I know I'm repeating myself :D)
<solnic>
it should be rarely needed to check object's state
<solnic>
I'm talking about specs that for example initialize an object and check its state - that's so terrible
<snusnu>
yeah, fine with me, with immutable objects, nothing can change them anyway
<snusnu>
yeah
<solnic>
snusnu: I also replaced rspec-mocks with bogus today
<snusnu>
i saw that, and i'm fine with that too :)
<solnic>
you don't have a choice, you could revert that but then I would revert your revert and then you would revert that etc etc
<solnic>
;)
<snusnu>
mwhaha
<solnic>
snusnu: just chatted with Dan, he's going to tackle SQL soonish
<snusnu>
re attr_reader specs, surely there must be *some* specs in the system that use the attr_readers to check if the op under test did the right thing
<snusnu>
it's silly to spec them in isolation
<solnic>
snusnu: yeah but I like to write specs that don't reflect on objects state
<solnic>
it's actually quite possible to do :D
<snusnu>
most of the specs for immutable code i wrote recently simply check if a result object is equal to a newly constructed object i expect
kapowaz has joined #rom-rb
<solnic>
snusnu: I also tend to avoid mocking these days, I've been abusing mocks for too long (like everybody has :P)
<snusnu>
solnic: hah, i remember when i stepped into dm-mapper code, i was like, wtf, mocks all over the place :p
<solnic>
yeah I always tried to mock external deps thinking I'd find concrete interfaces to depend on this way
<solnic>
but it was obviously STUPID
<snusnu>
solnic: btw, the style i currently do (i.e. comparing an op's result object to some constructed expectation object) implicitly relies on object state (thus actually tests the readers)
<snusnu>
solnic: the "assertion" is simply "pushed down" to equalizer doing its thing
<solnic>
yeah I saw that
<snusnu>
solnic: dude btw, when will you arrive in berlin? and when will you leave again?
<solnic>
need to think about this
<solnic>
snusnu: dunno yet
<solnic>
snusnu: first I need to know if I'm going alone or with my familia
<solnic>
but I think I want to spend at least 3 days there
<snusnu>
solnic: fair enough .. i dunno either yet, but i'm planning to stay a week at least .. most probably i'll go tuesday till tuesday, or something like that
<solnic>
snusnu: I'll let you know as soon as I...know
<snusnu>
sweet
<solnic>
snusnu: can you point me to some spec where you do that comparison thing?
<snusnu>
solnic: but it uses mocks only for the uninteresting things
<mbj>
sorry for uppercase got a capslock back from hibernation while diode is inversed o_O
<solnic>
gotta go, ttyl
<snusnu>
ok ttyl
<mbj>
ttyl
<snusnu>
mbj: so, do you agree that we should use ducktrap as our mapper, creating a ducktrap from our mapper dsl, specifying the way to *dump* and thus get load for free?
djsell has joined #rom-rb
snusnu has quit [Quit: Leaving.]
kleech has joined #rom-rb
kleech has quit [Ping timeout: 245 seconds]
snusnu has joined #rom-rb
<mbj>
snusnu: jo
<mbj>
snusnu: I found a loophole in the VAT system, nice.
<mbj>
snusnu: Just ordered my device, will squeeze out my old 2009 netbook.
mbj has quit [Ping timeout: 245 seconds]
mbj has joined #rom-rb
<elskwid>
Bah!
<elskwid>
By implicitly testing the Virtus ModuleBuilder there are some meta programming parts that drop the coverage down from 100%.
* elskwid
sighs
mbj has quit [Ping timeout: 284 seconds]
dkubb has joined #rom-rb
mbj has joined #rom-rb
<dkubb>
mbj: hello
<dkubb>
mbj: I heard from solnic that you're interested in working on sql generation with me
<mbj>
dkubb: jo
dkubb has quit [*.net *.split]
dkubb has joined #rom-rb
<snusnu>
hey dkubb
<snusnu>
dkubb: re that comment on set difference, i get it
<mbj>
dkubb: jo, I plan to work on the sql ast.
<mbj>
dkubb: Building an unparser for sql, just like I did the unparser for the ruby ast.
<mbj>
dkubb: I'll just spike something, I hope I can use this for my new client and back the db access with axiom ;)
<mbj>
dkubb: I'll define an ast/sexp format that will work nice for unparser
<mbj>
dkubb: This will hopefully be usefull as parsing output also.
<mbj>
dkubb: going to sleep now, cu
mbj has quit [Quit: leaving]
dkubb has quit [Ping timeout: 240 seconds]
dkubb has joined #rom-rb
djsell1 has joined #rom-rb
djsell has quit [Ping timeout: 276 seconds]
djsell1 has quit [Client Quit]
djsell has joined #rom-rb
solnic has quit [Quit: Leaving...]
djsell has quit [Read error: Connection reset by peer]