Arc Forumnew | comments | leaders | submitlogin
Arc + FleetDB - the schema free database optimized for agile development (blackstag.com)
7 points by thaddeus 4805 days ago | 6 comments


1 point by thaddeus 4805 days ago | link

Just figured out how to add things to my own Github. Haven't added to anarki yet since I'm just getting familiar with the whole open source thing :)

Please feel free to tear it a part or change it to your liking.

Note that I've also made changes/fixes to the json.ss lib file in anarki. You will need those changes, unless you use some other json library.

-----

1 point by thaddeus 4805 days ago | link

It's probably worth noting that the primary function is 'fdb-client'. Given the batch jobs are largely untested it may be worth just using this client call directly.

   (fdb-client 
      '("multi-read" '("count" "dogs") '("select" "dogs")))

-----

1 point by thaddeus 4804 days ago | link

OK, I changed the blog and the code. :) I think I was just adding too much unnecessary complexity.

-----

2 points by rocketnia 4804 days ago | link

I like both approaches. ^_^ I even think you may not have gone far enough with the complicated one. It would be pretty fascinating to make an s-expression DSL for this. From http://fleetdb.org/docs/queries/select.html, there's the list of "where" expression types:

  ["=",      <attribute>, <value>]
  ["!=",     <attribute>, <value>]
  ["<",      <attribute>, <value>]
  ["<=",     <attribute>, <value>]
  [">",      <attribute>, <value>]
  [">=",     <attribute>, <value>]
  ["in",     <attribute>, [<value>+]]
  ["not-in", <attribute>, [<value>+]]
  ["><",     <attribute>, [<low-value>, <high-value>]]
  [">=<",    <attribute>, [<low-value>, <high-value>]]
  ["><=",    <attribute>, [<low-value>, <high-value>]]
  [">=<=",   <attribute>, [<low-value>, <high-value>]]
  ["or",     <where-condition>+]
  ["and",    <where-condition>+]
It should be possible to add a "no" macro to the DSL, which compiles

  (no ("=" a b))           to ("!=" a b),
  (no ("in" a x y z))      to ("not-in" a x y z),
  (no (">=<=" a min max))  to (or ("<" a min) (">" a max)),
  and so forth.
We should also be able to abstract away operators like ">=<=" into more Arc-ish formats:

     (<= 100 "foo" 200)
  to (and (<= 100 "foo") (<= "foo" 200))
  to (and (">=" "foo" 100) ("<=" "foo" 200))
  to (">=<=" "foo" 100 200)
This should probably evolve into a more complicated system than normal Arc macros; there'd probably be a need to collapse things like (and (and ...) ...) so that subexpressions can be combined into their ">=<=" forms.

I know "more complicated" probably isn't everyone's thing, but I think it'll be a good way for me to practice some code generation techniques one of these days, unless someone beats me to it. ^_^

-----

1 point by thaddeus 4804 days ago | link

Thanks,

Your ideas would be ideal, though probably beyond my current skill set. I tried fiddling around with the original macro's, but I then started finding more problems than I was solving. So I changed it to be a dumb client version, just to make sure that if any newb (like me) started using the code, they would at least not get tripped up by all the bugs.

Any work you can contribute, even as a starting point, would be great and no doubt will prove educating to me.

-----

2 points by rocketnia 4803 days ago | link

The ideas were a bit more complicated than I knew how to break down into a quick running example. XD;; That's kinda why I just brain-dumped them into that post.

As a basic outline of the technique, imagine building a library of simple functions that construct FleetDB queries (which is to say, a combinator library), and then building macros on top of those to make them a bit nicer to use. That's most of what I'd do, except that I'd probably put in two extra abstraction layers:

- A translator for optimizing queries just before they're sent to FleetDB. This may or may not turn out to be helpful, depending on whether FleetDB does its own optimization. Also, this is a bit of a computational complexity rabbit hole, and I'm not sure how I'd begin to approach it. I'd probably just make it extensible so other people could try. :)

- A macro that takes an s-expression DSL and manually walks over it and converts it into calls to the combinator library. This would allow us to use operator names like 'or and '< without redefining Arc's own 'or and '<. This is probably where I can best help you out with a code example:

  (= dsl-macs* (table))
  
  (mac dsl-mac (name parms . body)
    `(= (dsl-macs* ',name) (fn ,parms ,@body)))
  
  (def expand-dsl (expr)
    (if atom.expr
      expr
      (let (op . args) expr
        (aif dsl-macs*.op
          (apply it args)
          expr))))
  
  (mac dsl (expr)
    expand-dsl.expr)
  
  
  ; FleetDB combinator
  (def fleetdb-or args
    (cons "or" args))
  
  ; FleetDB DSL extension using that combinator
  (dsl-mac or args
    `(fleetdb-or ,@(map expand-dsl args)))
Thanks to http://tryarc.org/, this is working code. :)

  arc> (dsl:or '("<" "foo" 1) (or '("=" "bar" "woof") '(">" "foo" 11))))
  ("or" ("<" "foo" 1) ("or" ("=" "bar" "woof") (">" "foo" 11)))
I've also posted this code to https://gist.github.com/808357 for posterity. ^_^

-----