Fork me on GitHub

What does this mean?


>; TODO: More complete covereage of queries in the context of UI. ; - Links (and the fact that a link-ONLY query still requires at least an empty thing in app state


Hm, so apparently if a link query is not at Root level it needs a non-nil field in the state where the linked state is going to go ?


Anyone know how I can get the send the database config to the EasyServer component ? (easyserver & server seem to only require only config-path)


thinking that me reading the config and sending the bits I need to (map->SQLDatabase {$config_options}) & untangled-server also reading from config-path is not ideal. Is there a flow I'm missing ?


@claudiu Above is how I did it just to start talking to some supplied datomic db.


what is build-database ? 🙂


Good question ...


Its a datomic call


[untangled.datomic.core :refer [build-database]]


@urbank Yeah, I need to get back to those TODOs 😉 Link queries are ones that go back to the root: '[ {[:person _] (om/get-query Person)} ]. If you do this query on some component in your tree and that is ALL you query for, then db->tree in the query processing won’t actually make it there unless the component you’ve got that query on also has some kind of data of it’s own (e.g. you cannot just query for things at root). That can be an empty map.


The config-path points to file where all the datomic stuff is set up.


@claudiu Depend on :config (and put your config in your config EDN). The config bit in Untangled on the server-side is a component that can be dependency injected…is that what you’re asking?


> unless the component you’ve got that query on also has some kind of data of it’s own This means that the component has an ident, not just that it queries for some other data as well?


well basically was asking: Untangled seems to read the config, how can I access what it read inside other components in the system 🙂


@urbank I don’t know if Ident affects this at all. I doubt it. It’s just that db->tree won’t recurse and process a component’s query if the spot for it in the db is nil/false


tony.kay: Hm... so component has some state is defined as component queries for some state without using a link query ?


No. Simply that there is something non-nil in the graph database for that component. An empty map is sufficient. I note it because it is surprising to have a query (which asks for something only from root) on a component that doesn’t work when nested in the UI…unless there is some kind of data path to actually follow to get to it.


Root -> A -> B with database {:p value :a {:b {}}} where B asks for [:p _] will work. But if the database was just {:p value} it won’t.


@tony.kay Ah, I see. That's clear now. Thanks!


Feel free to send a PR fixing that TODO 😉


@tony.kay Ok, hopefully it will be up to par 🙂


So I'm not sure where the explanation should go. D_Queries <- Added to the link query section E_UI_Queries_and_State <- Or in a new section here where the todo is?


where the TODO is. It won’t make sense until you’ve talked about both queries and state.


maybe a devcard with two siblings that both query only for a root prop. One with state and one without…showing how one works and the other does not.


Hm.. so unfortunately I haven't been able to get it working yet. Perhaps I'm misunderstanding something or maybe it's a small error I can't spot. I'll post some code. I'll get back to it tomorrow evening.


@claudiu Config is a built-in component with the ss component ID :config. Read stuart-sierra’s component library docs. component/using with :config will get you the config in your component, and they you can read it.


if you need it in the parser, add it to parser-injections and it will be in env


@tony.kay thank you. Reading component docs.


@tony.kay the recepy seems to use flyway, for connection. Is this how it should be used in production or just for learning purpose ?


I added HikariCP to my codebase, for pool


So, I recommend flyway because in dev AND production you want a clear way to tracking db migrations and making sure schema is identical. As far as connection management goes: I hard coded it there. The production-quality components I’ve written for this task are a lot more complex than what you’re looking at.


I have used Hikari as well, which is my preferred


some other requirements: 1. Migrations don’t auto-run in production mode (must be explicit, so you don’t migrate production accidentally) 2. App won’t start if migrations are not current (so you don’t start app on database missing migrations) 3. Test database can easily be created (I’ve written a macro test-database that I don’t have the rights to at prior company). starts a test db block-style, and tears it down at end of block


tony.kay: Noted. These things will have to be in my project also, will share what solutions I come up with 🙂


I’ll probably rewrite all this at some point. Only takes a couple of days, but actually…the test-database thing is db specific (I was using PostgreSQL and the macro was doing all of the setup, even to the point of starting a database server if needed)


It’s also useful to encapsulate the idea of a read-only connection into the system (that can be pointed at a read only replica)…there is some nuance to making that safe and usable


cool 🙂 It's for my work project. Changed to hikari since performance is a must (pool size, all that stuff), and don't know how performat using the connetion from a schema migration library would be.


Yes, you want a pool. The migration library is not for connection generation…it is for migration.


That demo code just doesn’t have pooling. It is being lazy and making a single connection that it uses everywhere…horrible for anything but a simple example. I was more demonstrating query processing with that demo, not production setup.


ahh cool 🙂 spent a few hours on this today (mostly because I'm a noob and don't know the ecosystem that well). Can share a example with Hikari, add it to the recipes if you want 🙂


What database you planning on using…mysql, you said?


not postgresql?


If you want to add a connection pool to that existing recipe, that would be fine. I don’t know that connection pooling as a stand-alone makes much sense. Not an untangled-specific issue


If you want to collaborate on building the SQL tools for untangled in general, we could start a new library like untangled-datomic. I have interest in it supporting PostgreSQL, and it sounds like you want MySQL. Those are two popular options. It could have connection pooling, migration support, and integration test support tools. I’ve already designed such a thing before…more than once, unfortunately. Would be nice to finally open-source it!


ahhh. A mysql (mariadb). Was just interested in getting a production app with mysql queries (it's a small project). Don't have that much experience with migration tools, usually do that by hand when needed.


Hm.. so unfortunately I haven't been able to get it working yet. Perhaps I'm misunderstanding something or maybe it's a small error I can't spot. I'll post some code. I'll get back to it tomorrow evening.


Perhaps I don't understand something about devcards?


@urbank I’d use InitialAppState and cards/untangled-app. You need a complete app


If you look at the source for 010-Forms-Full-Stack-Demo you’ll see that sort of thing in action


But good first try. Here’s roughly what you want:

(defui A Ident (ident ...) IQuery (query [this] [[:p '_]]) InitialAppState (initial-state [t p] {}))
(defui B Ident (ident ...) IQuery (query [this] [[:p '_]]) ) ; NO initial state
(defui Root InitialAppState (initial-state [t p] {:p 42 :a (get-initial-state A}) IQuery (query [this] [{:a (om/get-query A)} {:b (om/get-query B)}])
Now, A and B both ask for nothing except a root-link piece of data (which exists). A will get it (because the graph db allows A’s node to be reachable) and B will not. The defcard is:
(defcard my-card (untangled-app Root))


or course you’ll want to have a and b attempting to render what they get so you can see the result.


If you want, you can also see the devcard state with:

(defcard my-card (untangled-app Root) {} {:inspect-data true})