<snusnu>
solnic: ping me if you want to know about the motivation behind that
<solnic>
snusnu: ping
<snusnu>
lol
<snusnu>
so, it seems to me that since wrap/group can never be pushed down to SQL databases, doing those ops in (preregistered) relations hurts their composability
<snusnu>
so my plan is to define my relations without wrap/group ops applied, and let morpher do those ops when mapping to porors
<snusnu>
solnic: ^^
<solnic>
so you ended up with how it's like in ROM now
<solnic>
;)
<snusnu>
well not really, the way i see it
<solnic>
yes you did
<solnic>
you wrap/group later
<solnic>
which is how it works in ROM
<snusnu>
but rom performs wrap/group as RA ops
<snusnu>
i don't wanna do that
<snusnu>
s/RA ops/axiom ops
<solnic>
why?
<solnic>
axiom does that for you in memory
<solnic>
you just duplicated functionality
<snusnu>
exactly, but it cannot push down restrictions applied after that
<solnic>
yes you can
<snusnu>
so i cannot compose 2 relations with wraps applied, and THEN restrict it
<solnic>
I'm pretty sure it should just work
<snusnu>
nope it does not
<solnic>
if you compose things using gateways it should work
<snusnu>
people.join(accounts).wrap(:account, [:id, :login]).restrict(login: "snusnu") DOES NOT push the restriction down to the datastore
<snusnu>
nope dude, it does not
<snusnu>
test it
<solnic>
shit really?
<snusnu>
yes
<solnic>
yeah man lemme test it
<solnic>
but first
<solnic>
BBIAB :P
<snusnu>
obviously you can perform that restrict before the wrap, but as i said, this hurts composability
<snusnu>
btw, alf has the same "problem"
<snusnu>
it's really about SQL stores not being able to handle wrap/group
<solnic>
well
<solnic>
I can see how you could push it down in some cases
<snusnu>
yes you can, axiom-optimizer needs a few rules
<solnic>
JSON stuff in postgress for example
<snusnu>
but it will never be able to handle all cases
<snusnu>
yeah
<solnic>
axiom-optimizer?
<solnic>
not sure if that's the right place to do it
<solnic>
it's SQL-specific optimization
<snusnu>
nope
<solnic>
so the generator should optimize it, no?
<snusnu>
lemme explain
<solnic>
please do, I'll be back in literally 10 minutes
<snusnu>
axiom-optimizer can detect cases where it's safe to push wrap/group ops further to the leaves of the tree (ideally, they'll *always* be leaves)
<snusnu>
but it cannot *always* do it
<snusnu>
because (at least in pure RA) you can restrict on a wrapped attribute
<snusnu>
mbj: if you have a few minutes, i'd be glad to talk to you about wrap/group in morpher (group in particular)
<snusnu>
solnic: btw, you may have noticed that the wrap op i pushed to morpher allows to do renaming as well
<snusnu>
solnic: re axiom-optimizer, the way i see it, is that it's probably always safe to level up wrap/group ops if at least no restriction on the wrapped/grouped attribute happens *after* the wrap/group .. in general, you can probably say that if no operation involving the (T,R)VA is applied after wrap/group, it's safe to level it up
<snusnu>
solnic: also, with postgres JSON type, we could push it down i guess, the axiom-optimizer rules are simply for rewriting the RA tree so that these ops are applied *last*, because if they are, everything else can be pushed down to the datastore (well, at least ops that can be pushed down in the first case)
<snusnu>
to elaborate a bit more on my reasoning, i'm planning to be able to register (context aware, i.e. parameterized) relations in some sort of schema object, and be able to use those relations when composing others
<snusnu>
therefore, as soon as one of these registered relations has a wrap/group applied to it, every other op coming after these (e.g. a restrict) cannot be pushed down to the datastore anymore, leaving us with very inefficient queries
<snusnu>
to avoid that, i've decided to never apply wrap/group in my schema relations, but instead let my mapper handle it
<snusnu>
since my mapper is based on morpher, i've pushed support for that to morpher
<solnic>
I suspect ROM could levarage that addition too
<snusnu>
my mappers (if they need wrap/group) will now initially see a *relation* (not a tuple anymore) and perform the ops on that
<snusnu>
i'm pretty sure it could
<solnic>
I still don't understand why you want to have that pure axiom schema ;)
<snusnu>
lemme just say i wanna try how it feels … i wanna shift focus away from objects, closer to relations .. i want to have some viewpoint concept like bernard does
<solnic>
you can have the same thing with relation already wrapped with gateways
<solnic>
gateways *are* relations
<snusnu>
dude, i know :) i have working code for that already
<solnic>
unless you're drifting towards a different concept, ie no gateways and using something else
<snusnu>
the only different concept i'm drifting to is trying to expose fully composable relations, and only access those in my read views
skade has quit [Ping timeout: 240 seconds]
<solnic>
how does it differ from rom schema?
<snusnu>
when i actors = accounts.join(people).restrict(login: login).sort .. i want to do that *ONCE* in my schema, and after that, only do stuff like employment = company.join(actors('snusnu'))
<snusnu>
the way i see it, rom schema defines base relations and maybe a few virtual ones, but apart from that, relies on "ad-hoc" queries in (read) actions
<snusnu>
i want all those relations, that give me data i need in views, preregistered, with a name, to be able to access (and compose) them
<solnic>
dude, it's up to you to register whatever you want
<snusnu>
dude, try to register a context aware relation in rom-schema
<solnic>
context-aware?
<snusnu>
one that accepts parameters (e.g. for restrict)
<snusnu>
a join is mostly no use
<snusnu>
you need to restrict almost always
<solnic>
if you want further restrictions you need to call restrict on the registered one
<solnic>
how otherwise you could do that?
<snusnu>
i don't want to do those restrictions in "client code" (ad-hoc queries) .. but already register these context aware relations in a schema
<snusnu>
much like bernard does with his concept of viewpoints
<solnic>
so
<solnic>
you have a relation that accepts params
<solnic>
and it knows those are just to restrict
<solnic>
but you don't call any of ra ops
<solnic>
you call...what do you call? just refer to the relation and pass in params?
<snusnu>
a current spike i have locally defines the relation in a parameterless block, but wraps this block in another block accepting the params (so that they get bound when accessing the schema slot) .. in order to produce the actual query, i need to do stuff like schema[:actors].call(account_id).to_a
<snusnu>
that way of doing it can definitely be enhanced ...
<snusnu>
yeah i *really* wanna try an app written like this
<snusnu>
btw, in the pastie above, you still see the wrap in the relation, this is going to go away once morpher has full support and i added it to my mapper
<snusnu>
solnic: once can think of this as somewhat related to named scopes in other orms, but fully composable
<solnic>
scopes are methods on relation objects
<solnic>
those are scopes on their own
<solnic>
"views" is a better term
<snusnu>
i agree
<snusnu>
it's a bit overloaded with (web) app views, but yeah
<snusnu>
the official RA term(s) seem to be virtual or derived relations
<snusnu>
but those aren't parameterized
<solnic>
is there a name for parameterized views?
<snusnu>
not that i know, bernard introduced the concept of viewpoints, which basically are little schema slices, consisting of only the relations/views that are necessary to construct an (app) view
<snusnu>
i really like that
<snusnu>
it seems that his viewpoints can declare which other viewpoints they depend on
<snusnu>
so you basically have a place where all views that you need to construct a viewpoint, are available
<snusnu>
he also does trickery (like #method_added) were he allows to declare those parameterized views as ordinary ruby methods
<solnic>
interesting
<solnic>
what about naming?
<snusnu>
i don't know if i want to go this far, at least not before trying to use it differently
<solnic>
:sorted_active_users sucks
<snusnu>
well, it sucks, but at least partly because you (we) are not used to it so far
<solnic>
how about having a tree
<solnic>
and access via method calls
<solnic>
sounds better IMO
<solnic>
would look like scopes
<snusnu>
yeah, that's like bernard does it
<solnic>
users.active.sorted
<snusnu>
i'm not even sure if i wanna expose methods on objects tho
<snusnu>
because then you just shift the naming difficulties to naming the classes
<snusnu>
hmm ok, users.active.sorted is different from what bernard does at least
<snusnu>
i wanna see how far i can go with registering relations in a (global) schema for now
<solnic>
it's just a matter of defining accessor methods on those viewpoint objects
<snusnu>
sugar can always be sprinkled on top after
<solnic>
ok sure that's a good start
<solnic>
yep
<solnic>
I've got an ast question /cc mbj
<snusnu>
there's just one difference i haven't yet thought deeply about (re wrap/group in morpher)
<solnic>
snusnu: have you ever had a case where you'd like to merge 2 ast nodes?
<snusnu>
and that's the fact that for this to work, morphers (aka mappers) must operate on a relation instead of a tuple
<solnic>
snusnu: I mean s(:fields, s(:id, 'name')).merge(s(:fields, s(:id, 'title')) => s(:fields, s(:id, 'name'), s(:id, 'title'))
<solnic>
this is need for collapsing multiple selects into a single one with inner join
<solnic>
I've got it done locally using ad-hoc code but now I'm thinking about encapsulating this logic in a reusable class
<snusnu>
i would do that in a preprocessing step
<snusnu>
because essentially you're rewriting the ast, no?
<solnic>
what's the difference between processing and preprocessing?
<snusnu>
you register a preprocessor for, say, natural join, that receives the node, and then you construct another node out of that info
<solnic>
I take axiom ast and turn it into sql ast
<snusnu>
take the morpher example for wrap/group .. the (user facing) sexp is: s(:wrap, :name, [:attr_1, :attr_2])
<solnic>
ah so preprocessing would translate axiom ast to sql ast and that would be processed to optimized sql ast with one select and inner join
<solnic>
right?
<snusnu>
the internal/rewritten sexp is: s(:_wrap, s(:static, :name), s(:static, [:attr_1, :attr_2]))
<snusnu>
yeah solnic
<solnic>
yeah I thought about doing it like that
<snusnu>
a preprocessor receives a sexp, and it turns it into another sexp
<solnic>
I thought I could skip that part but it is not realy feasible
<snusnu>
s/sexp/node
<snusnu>
i'm pretty sure it'll be needed
<snusnu>
you can cargo cult (!) the preprocessor architecture from morpher
<solnic>
yeah because you want to construct individual nodes to see what fields, where clauses, order by clauses etc are there
<solnic>
I already cargo culted (!) emitters
<snusnu>
yeah, preprocessing is always handy when you want to support a simpler sexp that can be rewritten to something more complex (potentially using other primitives, as in the case of morpher)
<solnic>
couldn't work with built-in processor for too long :(
<snusnu>
yeah, morpher's a nice codebase for stealing ast processing code
<solnic>
I will try this approach with 2-step processing
<snusnu>
solnic: got a minute to think about potential implications when (sometimes) feeding mappers with relations as compared to tuples?
<solnic>
why would you want to do that?
<snusnu>
with dm-mapper, it was like that anyway .. with morpher, i actually see no real problem, still, i'm far from saying that i'm aware of all implications
<snusnu>
because of #group
<snusnu>
it cannot work on a tuple
<solnic>
rom mappers support wrap and group
<solnic>
w/o knowing about relations
<snusnu>
lol because axiom does it
<solnic>
yes and?
<snusnu>
i'm talking about wrap/group in morpher
<snusnu>
for morpher to be able to perform a group, it must receive a relation as input
skade has quit [Ping timeout: 240 seconds]
<snusnu>
(just as axiom obviously receives one)
skade has joined #rom-rb
<snusnu>
mbj: any thoughts on group in morpher? (particularly about the fact that it most operate on a relation as input)
<solnic>
snusnu: I think it's working around the problem
<solnic>
it should be handled by axiom
<snusnu>
i know man, but unless we get postgres json support (very soon), i have to workaround it, if i want to continue on my path
<solnic>
I will think about it later, I need to focus on work now
<solnic>
isn't it just a matter of moving restrictions to coresponding relations?
<mbj>
solnic, snusnu: Morpher and axiom are IMO orthogonal to each other. I expect concepts from each make sens for the other.
<solnic>
should be doable in the sql processing
<mbj>
snusnu: I do not have the time to review it in depth now. Sorry.
<snusnu>
that could handle a lot of cases, but not all of them (probably enough in practice tho)
<snusnu>
solnic: ^^
<snusnu>
solnic: ping me once you have more time again
<snusnu>
there are a few other factors that come into play when deciding what does the wrap/group, axiom or morpher
<mbj>
snusnu: I think on the longterm it makes sense to have those node in both libs.
<mbj>
snusnu: axiom is great for relational structured data.
<mbj>
snusnu: morpher fills the gap, meaning: you can turn arbitrarily structured data (from API, POST, request params) etc into a well defined structure, that must not but can: be a relation.
<mbj>
snusnu: Also it allows to turn relation tuples into domain objects and vice versa.
<mbj>
snusnu: So it makes sense we have two libs that share *some* power. But IMO we should reduce the amount of duplication.
<mbj>
snusnu: I expect that it should be possible to port some of the nice morper internals (AST compiler, preprocessor) to axiom.
<snusnu>
mbj: i can totally imagine wrap/group being useful outside of a relational context
<snusnu>
mbj: but for now, really, i only think of it as a workaround because of the pushdown problem
<mbj>
snusnu: Also I expect we should externalize all that nifty AST helpers, named children, emitter registry & lookup, emitter boilerplate.
<snusnu>
pease yes
<mbj>
snusnu: I have duplicates of them in: morpher, mutant, unparser, sql, axiom-ast, aql (soon).
<snusnu>
please go ahead and exract it then :)
<mbj>
jep
<solnic>
yeah I kinda started doing that in axiom-sql-generator
<solnic>
under Axiom::AST
<mbj>
solnic: Do you have a good name?
<solnic>
...
<solnic>
ast-processor :P
<mbj>
ASTUtils (namespace), ast-utils (gem)
<mbj>
or astutils (gem)
<solnic>
ast-util sounds good
<solnic>
it is that after all
<snusnu>
solnic: i think we could solve 95% of real life cases if we were to encode a few RA tree rewrites in axiom-optimizer, that level up wrap/group ops when possible
<solnic>
but we have a name clash with AST::Processor
<mbj>
Meh, I want to have more time here. Seems I have the chance to bring us forward significantly in lets say: a day of concentration.
<solnic>
snusnu: I will get to optimizer...at some point ;)
<mbj>
Sorry for me being absent, but I'm BUSY.
<solnic>
mbj: you are not absent lol you are just chatting with us
<snusnu>
solnic: i think it might always be possible if no ops further down the tree involve the (T,R)VA
<mbj>
solnic: its very easy to join a channel and say stuff like: "Do that", "Do this", "thats correct this way" etc.
<mbj>
solnic: Thats not my fav style of contribution.
<mbj>
solnic: I want to prove my claims.
<snusnu>
mbj: fwiw, i somewhat think that #group isn't really nice to be done with morpher in a relational context … at least it'd need special casing in Relation#each based on the presence of a group op in the injected mapper
<snusnu>
mbj: unfortunately, i still think it'd best be done in morpher, given the current axiom pushdown constraints
<snusnu>
i'm going to look at axiom-optimizer now tho, to see if i have ideas on how to perform a few simple optimizations that level up wrap/group when possible
<mbj>
snusnu: Just remember axiom also has an implicit ast.
<mbj>
snusnu: The #class attribute of a relation is the type
<mbj>
snusnu: And the exposed attributes are the children.
<mbj>
snusnu: Because axiom has an unexplicit AST transforming is a bit more unnatural. We'll gonna fix this ;)
<snusnu>
i know, but i have NO IDEA how to implement the optimizations, i don't even know the rules
<snusnu>
like when can i optimize, and how
<mbj>
snusnu: If you have a "pure" AST, where the nodes are most primitive, most optimizations happen on a per node level.
<mbj>
snusnu: So you just look at the current node and match specific children characteristica.
<snusnu>
i just have a feeling that i need to walk the tree until i find the deepest wrap/group, and then walk back to the leaves, and if no op (like restrict) involves the (T,R)VA, the wrap/group op can be moved closer to the leaves
<snusnu>
see, i don't even know the characteristica
<mbj>
snusnu: What I told above has bubble sort characteristica, but it *works*.
<mbj>
snusnu: For the first stages I'd just rerun the optimizer as long there are still changes to the AST.
<snusnu>
it does that by default from what i can tell
<mbj>
snusnu: Later we can optimize the optimizer to do it more efficiently.
<snusnu>
damnit i'm not sure if i should tackle this right now ...
<snusnu>
the thing is, i'm pretty sure that with the proper set of optimizations, the pushdown problem would not be one in 95+% of practical queries
<mbj>
snusnu: You can also write a "your domain specific optimizer".
<mbj>
snusnu: That only does the lift/push-down of group/ungroup.
<snusnu>
that amounts to the same thing
<snusnu>
potentially even more work
<mbj>
snusnu: no
<mbj>
snusnu: 99% of the nodes would be handled by a generic catch-all noop optimizer.
<mbj>
snusnu: Only if you see a wrap-unwrap in children you take action.
<snusnu>
it should be reasonably easy to find out how i'd get axiom-optimizer to only work on those ops too
<snusnu>
from then on, it's the same work
<snusnu>
but without the boilerplate around everything
<solnic>
snusnu: how about you start by porting the optimizer to use ast? :D
<mbj>
yeah. I was talking about a ast based axiom.
<mbj>
solnic: do you have axiom-relation <=> axiom-ast already?
<snusnu>
solnic: i have no time for that now sorry
<snusnu>
i need to closely work on features i *use*, otherwise i can't justify time spent
<mbj>
I could target all that stuff that blocks you guys here. Just because I'm used to do such transforms I could make it happen pretty fast.
<snusnu>
man, don't always say that ;)
<snusnu>
do it
<snusnu>
:p
<mbj>
I'll hope I can do an OSS cycle. Yesterday did not worked out. Sorry.
<mbj>
snusnu: close to zero OSS time, thats my problem.
<snusnu>
i know dude, that's why i'm saying don't say that
<snusnu>
hehe
<solnic>
mbj: currently I'm focusing on one way relation => ast
<mbj>
heh
<solnic>
but I will get <=> eventually
<solnic>
it's easy stuff
<mbj>
solnic: hint: its easier to do it for both sides directly.
<mbj>
solnic: Because you do not have to redo your one way in case you find you lost information.
<snusnu>
solnic: +1 to what mbj said here
<mbj>
solnic: you'll run into it. Just as you run into the need for the emitter based ast transforms, with children naming etc ;)
<solnic>
I like running into things
<mbj>
solnic: I'm very happy it turned out to be useful for you.
<solnic>
I can't maintain such a big context in my head
<solnic>
so, I focus on understanding how SQL can be done
<solnic>
once I see it
<mbj>
solnic: yeah, I do not want to stop you running into it. I only want to incept my solution idea for the "after you ran into it". Just like I did with the "use the same stuff I have in morpher" ;)
<solnic>
I'll move to turning ast into relations
<solnic>
well ok I'll try to do both ways
<solnic>
that will add some extra time though
<mbj>
k, transitive properties reduce the amount of unit specs to write.
<mbj>
See unparser.
<snusnu>
solnic: one could argue that once your mind is occupied with the code to generate sql from a relation, it's right on the spot where the other way happens as well … not such a big context shift
<snusnu>
(that's my experience, when spiking axiom-schema)
<solnic>
I guess you're right
<mbj>
I just have a gigantic list of ruby snippets, that allow to cover all branches of unparsers code.
<solnic>
btw I think it's better to test sql-generator using actual SQL strings
<mbj>
Thats my unit test, with the next versions of mutant I do not have to specify anything else. Hopefully.
<solnic>
there's a risk matching ast nodes will get out of sync
<solnic>
meaning sql-generator tests are passing
<mbj>
solnic: depends.
<solnic>
but sql generation is broken
<mbj>
sql strings are just an representation of sql-ast.
<mbj>
solnic: You are aware dan build an sql parser and sql emitter in his sql gem?
<solnic>
my point is that you can change something in sql gem and we won't see it
<solnic>
yes
<solnic>
I use it
<solnic>
I merged it in in the rom's fork
<mbj>
solnic: I think its the trust your dependencies rule.
<solnic>
so it's master now :P
<mbj>
solnic: I'd only spec against the intermediate representation that reaches the sql gem.
<solnic>
I think I'll end up with a shared spec that will have a looooooon list of sql queries
<solnic>
and test against that in both places
<mbj>
solnic: That could be named as property based testing.
<solnic>
I keep jumping between sql and sql-generator
<solnic>
to make sure the nodes are correct in my test examples
<solnic>
kinda annoying
<mbj>
I'm not 100% sure at this point, but I expect property based testing (as used in haskell) can reduce some of the boring unit tests we write these day.
<solnic>
I suspect it won't be an issue after I remember all of that
<mbj>
solnic: It goes pretty fast.
<solnic>
we'll see
<mbj>
solnic: I remember the structure of all ruby AST nodes now, after finishing unparser ;)
<solnic>
sure man
<solnic>
blah
<solnic>
I need to go guys
<solnic>
ttyl
<snusnu>
ttyl
<mbj>
solnic: And learning another language is basically learning the AST now.
<mbj>
I never liked Haskell in my earier tries, but now I can read .hs sources, see the AST it produces and I'm happy.
cored has joined #rom-rb
cored has joined #rom-rb
<mbj>
Actually I think stuff like precedence is tought people the wrong way. "foo gets executed before bar because operator has more precedence etc" - statements you see in typical university courses is plain misleadning.
<mbj>
IMO they should always show an AST to illustrate it.
<mbj>
because the execution order depends on the AST and the way the bytecode-emitter (interpreter) walks through it.
<solnic>
imagine a hamster laughing, that was that
<snusnu>
mwhaha
<solnic>
:)
<solnic>
sorry, I'm being silly, it's a stressful Monday for me to be honest ;)
<snusnu>
no worries man
<solnic>
what I wanted to say is - thanks for sharing
<solnic>
I'm going to browse through the sources
<solnic>
looks like Entity is kinda like Mapper in ROM
jordanyee has quit [Quit: MacBook went to sleep.]
<snusnu>
yeah, the code was always available in the subway repo, but i figured it's time to split it out as it really has NOTHING to do with the rest of subway, i just started spiking in there ..
<snusnu>
yeah the entity part is what i use for parameter sanitization and for db reads
<solnic>
I'll incorporate those ideas into ROM soon
<solnic>
I got very busy with AST etc
<solnic>
so ROM is kinda on-hold
<snusnu>
well, all the work you do is for rom's benefit, so i wouldn't call it on hold
<solnic>
yeah I know
<solnic>
that's why I do it
<solnic>
it's gonna take a while before things I work on can be merged into axiom mainline (which assumes Dan would be interested in merging those changes in)
<solnic>
I'm not sure what to do in the meantime
<solnic>
maybe rom-axiom or something
<solnic>
would be a solution for now
<snusnu>
sure why not
<solnic>
snusnu: I gotta say this stuff is getting more and more exciting
<solnic>
it's funny but I'm still fighting with my AR-infected mind
<snusnu>
yeah, same here, even tho i'd say i'm still fighting (to some extent) with my DM1 infected mind
<snusnu>
because really, there's no diff
<solnic>
details details
<snusnu>
and btw, i think/hope that rom and ramom will be able to feed off each other
<snusnu>
i like to think about ramom as the more experimental playground
<snusnu>
a place where, sorry to say that, i don't have to discuss everything if you know what i mean ;)
<solnic>
snusnu: we all know what you mean ;)
<snusnu>
hehe
<snusnu>
i'm also perfectly happy if at some point the need for ramom goes away and i can switch to rom proper .. for the time being tho, i'm gonna keep on pushing ramom towards my needs
<solnic>
snusnu: I'm hoping for a merger :)
<solnic>
NOT like merb+rails though LOL
<snusnu>
mwhaha
jordanyee has joined #rom-rb
jordanye_ has joined #rom-rb
<solnic>
snusnu: ideas I really like are relation "views" and entity builder
<solnic>
I'm definitely supporting those concepts and it will be included in ROM
<solnic>
I'm 100% sure ROM will have the same features eventually
<solnic>
I'll add them once I'm done with basic SQL generator working
<solnic>
by saying basic I mean that entire ROM suite passes on axiom-do-adapter
<solnic>
this will be enough for me
<solnic>
and I will mark it as good enough to move on
<snusnu>
nice, i will further experiment with adding FK constraints to my schema … the way i see it now, those are the last remaining pieces so that mappers can automatically be created
<snusnu>
at least the mappers i use
jordanyee has quit [Ping timeout: 240 seconds]
<snusnu>
the reasoning behind it is as follows: i have a "natural join optimized" database schema, i.e. i have db columns like accounts.account_id, account_email, etc … i always prefix the column name with the singularized table name
<snusnu>
the only exceptions from this prefixing, are FKs
<snusnu>
they don't get prefixed, so that by default, my schema is natural joinable
<snusnu>
now if my schema knows the FK constraints, it can apply the necessary renaming ops for my mappers
<solnic>
that one is covered in rom
<solnic>
you can rename stuff to be 'naturally joinable'
<solnic>
so, naturally, it works
<solnic>
if you want to keep non-prefixed ids you can rename them on the mapping side of things
<snusnu>
i can do that as well (renaming in mappers), and i can infer the names for all but the foreign keys already
<solnic>
I'm trying to make it possible to have ROM usable with "legacy" schemas
<snusnu>
my requirements are "special" in the sense that, before anything, i want to map to my app's schema
<snusnu>
my goal is to eventually be able to not define mappers at all
<snusnu>
i want them to be completely inferred
<snusnu>
but without relying on RA ops available on mappers
cored_ has joined #rom-rb
cored has quit [Ping timeout: 255 seconds]
<solnic>
snusnu: I'm not sure why you're so anti-ra-ops on mappers
<solnic>
I think a convenient interface available in mapper is a nice thing to have
<solnic>
regardless if you're using it or not in most of the cases
<solnic>
I see ROM using this interface under the hood to set up mappers
<solnic>
remember I still want to keep dynamic quering
<solnic>
even though I feel like upfront relation schema / mapping setup is a better thing to do
<snusnu>
my stuff would also support dynamic querying
<solnic>
how would mapper API look like then?
<snusnu>
re ra ops on mappers, i somehow don't really believe (anymore) in the idea that everything is a wrapper on top of relation (api)
<snusnu>
i have usecases for my mappers, which are COMPLETELY orthogonal to any relation based stuff
<solnic>
rom mappers are not wrappers on top of relation
<solnic>
they are a separate thing
<snusnu>
also, a relation actually already describes how a mapper would need to look like
<solnic>
rom relations use mappers
<snusnu>
so it should be possible to infer a mapper, solely based on any relation header
<solnic>
not really
<solnic>
partially, yes
<solnic>
but not in 100%
<snusnu>
gimme a counterexample
<solnic>
currently in rom you can do :rename => :foo in schema and in mapper map :bar, :from => :foo
<solnic>
I like that flexibility btw
<snusnu>
yeah, i support that on the mapper too already, my schema currently is a bit different (there's no base relation construction api for now, as i infer base relations from DataMapper::Model.descendants)
<snusnu>
also, i have no need to rename in the schema, because i control the db anyway
<solnic>
I want the system to be built internally in a way that allows you to jump into to the console and easily do stuff too
<solnic>
if it's built in a way that requires heavy DSL-based setup up front, then I consider this as a mistake
<snusnu>
absolutely
<solnic>
having all the schema definitions, mapper inferring etc is great, but all those individual objects should also expose a convenient API if you want to use something standalone
<snusnu>
of course
<solnic>
so I don't understand what's wrong in having an interface on the mapper layer that allows you to compose/reconfigure mappers :)
<snusnu>
there's probably nothing wrong with it, but i'm pretty sure it can be done differently too :)
<solnic>
how?
<solnic>
I really like the fact it's defined on the mappers, not somewhere else
<solnic>
less objects to deal with
<snusnu>
like i said, given a relation header, i should be able to construct mappers on the fly .. obviously, i have a Relation object that gets a mapper injected, so i can do that too
<solnic>
I mean, you can always build a morpher sexp yourself :D
<snusnu>
my current mappers were developed solely for the purpose of sanitzing input parameters .. they have nothing to do with RA, but as it happens, they seem to be enough to still handle that usecase, so why start duplicating all the RA ops on mappers now
<snusnu>
when i have other ideas how to do it
<solnic>
what are those ideas?
<snusnu>
it's all good too, we can test both approaches
<snusnu>
well, the idea is to take a relation header, and generate an appropriate morpher by reflecting on the header
<solnic>
you know that ROM mapper is now a DSL on top of morpher, right?
<solnic>
nothing more than that
<snusnu>
and you know that ramom mapper also is .. and has been before rom-mapper, right?
<solnic>
and you know that ROM takes a relation header and builds a mapper based on that, right?
<solnic>
I think we're talking about the same thing
<snusnu>
with different approaches
<solnic>
not really, you're just stuck on those RA-like methods on mappers
<solnic>
I may rename them to avoid confusion
<snusnu>
that'd only increase confusion imo
<solnic>
haha
<solnic>
ok
<snusnu>
also, fwiw, i'm not constructing mappers on the fly, with every applied RA op, but i just take the "finished" relation, and construct one mapper on top of that info
<snusnu>
well, i'm planning to do that to be honest ;)
<snusnu>
so my system will just care about relations (no mappers involved) .. the schema will be defined with relations only … and as an optional step, be able to generate mappers too
<solnic>
it's the same in ROM
<solnic>
it's really, exactly, the same
<solnic>
building things on the fly happens when you're doing adhoc queries
<snusnu>
i don't think so altho i'd love to be proven wrong … iirc rom when two relations are joined, their respective mappers are joined too
<solnic>
if you define things in the schema mappers will be generated once
<snusnu>
and that also happens if you define the relation in the schema, no?
<solnic>
I didn't get that far ;)
<snusnu>
if you join two rom relations, under the hood (in ROM::Relation) the 2 mappers involved are joined too
<solnic>
yes
<snusnu>
the way i imagine it, that doesn't happen
<solnic>
it doesn't hurt IMHO
<solnic>
I *like* the composability that was introduced with both composable mappers and relations
<snusnu>
i'm not saying it hurts, i'm just saying that this way of doing it would add shitloads of api to my mappers, that is completely useless for my other usecases
<solnic>
I see your POV
<snusnu>
you designed your mapper with ROM in mind, i designed mine for input sanitiztation .. more precisely, as a morpher dsl
<snusnu>
so my mapper already supports quite some stuff rom-mapper doesn't (and doesn't have to)
<solnic>
yeah
<snusnu>
adding even more api wouldn't be cool with me
<solnic>
coercion
<snusnu>
obviously, coercion is completely optional for my mapper
<snusnu>
it's handled by user defined type(s coercers)
<solnic>
I wouldn't mix those two
<snusnu>
yeah
<snusnu>
exactly
<solnic>
imo completely diff concerns
<snusnu>
complteley
<solnic>
good
<snusnu>
it just so happens that essentially, a hash_transform morpher is enough for ra mapping
<snusnu>
which obviously is part of my other needs
<snusnu>
so yeah, i want to have it completely decoupled from RA .. but still be usable
<snusnu>
if it turns out that i fail at doing so, ok, then i need to approach things differently.. for now, i'm confident that it'll work out well
<snusnu>
really tho, all the information in a relation header, should be enough to construct a mapper for that .. no matter how complex the relation
<snusnu>
so why create intermediate ones all the time
<solnic>
for adhoc queries
<solnic>
once you joined something you need a new mapper
<solnic>
once you renamed an attr, you need a new mapper
<snusnu>
nope
<snusnu>
not if you only construct it at the end in the firstplace
<solnic>
HOW would you do that?
<solnic>
inside #each ?
<snusnu>
for ad-hoc queries it's the same … define the ad-hoc query, use it in a mapped schema, get the mapper constructed for you on the fly (but not by applying ops for every RA op, but once, at the end, when the relation is "finished")
<solnic>
you do users.rename(:user_name => :name).project(:id, :name).join(:tasks)
<solnic>
how do you find a good place to construct a mapper at the end?
<solnic>
other then inside #each
<solnic>
s/then/than/
<snusnu>
good question, i'll roll a cigarette and come up with an answer :p
<solnic>
snusnu: lol :)
<solnic>
you go and do that
<solnic>
MAYBE injecting mappers into relations and this whole concept in general isn't a good one (lol)
<snusnu>
fwiw, my relation wrappers do that too, get a relation and a mapper injected i.e.
<solnic>
maybe we need to this proxy thing I talked about with dynamic queries and THAT thing should use mappers
<solnic>
blah
<solnic>
no
<solnic>
stop
<solnic>
I'm gonna go for a smoke too :P
<snusnu>
mwhaha
<snusnu>
you go and do that
<solnic>
see, that's why I need to start using ROM in something real, otherwise it's gonna be a fucking endless discussion about how stuff should work LOL
jordanye_ has quit [Quit: MacBook went to sleep.]
onewheelskyward has quit [Ping timeout: 252 seconds]
onewheelskyward has joined #rom-rb
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
snusnu has quit [Ping timeout: 276 seconds]
snusnu1 has joined #rom-rb
cored_ has quit [Ping timeout: 240 seconds]
mbj has joined #rom-rb
cored has joined #rom-rb
cored has quit [Changing host]
cored has joined #rom-rb
CraigBuchek has quit [Quit: Leaving.]
lgierth has joined #rom-rb
skade has quit [Quit: WeeChat 0.4.3]
snusnu1 has quit [Ping timeout: 252 seconds]
jordanyee has joined #rom-rb
snusnu has joined #rom-rb
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
mbj has quit [Quit: leaving]
postmodern has joined #rom-rb
snusnu has quit [Quit: Leaving.]
ptico has joined #rom-rb
bf4 has joined #rom-rb
CraigBuchek has joined #rom-rb
solnic has quit [Quit: Leaving...]
solnic has joined #rom-rb
ptico has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
solnic has quit [Quit: Leaving...]
snusnu has joined #rom-rb
snusnu1 has joined #rom-rb
snusnu has quit [Ping timeout: 252 seconds]
snusnu1 has quit [Client Quit]
lgierth has quit [Ping timeout: 252 seconds]
snusnu has joined #rom-rb
snusnu1 has joined #rom-rb
lgierth has joined #rom-rb
snusnu has quit [Ping timeout: 252 seconds]
jordanyee has quit [Quit: MacBook went to sleep.]
jordanyee has joined #rom-rb
jfredett-w has quit [Read error: Connection reset by peer]
snusnu has joined #rom-rb
snusnu1 has quit [Ping timeout: 276 seconds]
CraigBuchek has quit [Quit: Leaving.]
snusnu has quit [Ping timeout: 265 seconds]
lgierth has quit [Quit: Ex-Chat]
lgierth has joined #rom-rb
lgierth_ has joined #rom-rb
lgierth_ has quit [Remote host closed the connection]