Skip to content

Rework Query-DSL command. Add new Macro builtin command. Rework error handling. Updates Docs. Testcases#3

Merged
SerhiiRI merged 9 commits intomainfrom
macro-fix-query-dsl
Oct 29, 2025
Merged

Rework Query-DSL command. Add new Macro builtin command. Rework error handling. Updates Docs. Testcases#3
SerhiiRI merged 9 commits intomainfrom
macro-fix-query-dsl

Conversation

@SerhiiRI
Copy link
Contributor

No description provided.

…uction that can be reused, or usage can be not so pretty, so you decide to packed it in macro. Another way to usege is if you are have a Instruction that must be built in dynamic way with clojure code.

- UPDATE QueryDSL. From now it support 3 different type of resolvers:
1. resolve-instruction-qe for commando-resolve instruction
2. resolve-instruction for execution any kind of instruction
3. resolve-fn for function that must be resolved while it being asked by
QueryExpression
- UPDATE QueryDSL. Better error handling.
- UPDATE Registry. Built registry contain also internal commands of Instruction.
multimethod it can be expanded by another Exception types. Serialized
object contain neccessary information declared in keywords, and the
:data key (even if it contains symbols, etc.) wrapped to string. To
avoid default conversion of :data key to string use
commando.impl.utils/*debug-mode*.
- FIXED Tests for exceptions.
@SerhiiRI SerhiiRI self-assigned this Oct 22, 2025
SerhiiRI and others added 2 commits October 22, 2025 22:08
unit testing for QueryExpression corner cases like sequentual return data.
- FIXED QueryDSL. Fixed small issue with Exception on cljs.
- FIXED QueryDSL. Automaticaly handle in ->query-run the any different
types which are not the Resolvers object

Co-authored-by: Julia47 <julia.burmich@gmail.com>
@SerhiiRI SerhiiRI requested a review from Kaspazza October 23, 2025 06:00
@SerhiiRI SerhiiRI marked this pull request as ready for review October 23, 2025 06:01
- UPDATED the Commando Query DSL documentation to enhance clarity and detail, including examples and explanations of core concepts, lazy resolution, parameterization, and real-world applications.
…ain multiple keys('flags') what can change the behavior of commando/execute
Copy link
Contributor

@Kaspazza Kaspazza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, great changes! Good job!

macro-data (dissoc m :commando/macro)
result (commando/execute
(utils/command-map-spec-registry)
(command-macro macro-type macro-data))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be infinite loop if macro extends itself. Which in a nature of this command being used as a quick development tool (as it's alternative to creating a whole new command) I think it's possible to happen.

WDYT about checking expansion depth?
Something like:
(def ^:dynamic macro-expansion-depth 0)
(def ^:private max-macro-expansion-depth 10)

:apply (fn [_instruction _command-map m]
(when (> macro-expansion-depth max-macro-expansion-depth)
(throw (ex-info "Macro expansion depth exceeded"
{:macro m :depth macro-expansion-depth})))
(binding [macro-expansion-depth (inc macro-expansion-depth)]
...))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, i also thinking about it, but based on fact that instructions with macro approach staying some sort of building blocks, the limits by depth can make some risk of usage it, especially if you want to build your logic with huge amount of macrosses that somehowe combine together.
The main feature with using such kind of tool that you do not thinking about hidding limitation you can take. If your machine can do it - do it.

i think we need to make some limitation by depth it should be number of 1000, somewhere neer the region of StackOverflow exception and try to catch it before it gone. Or another, if the StackOverflow is riched, than process this error properly

QueryExpression))

(deftype ^:private QueryResolve [value Instruction]
(deftype ^:private Resolver [resolver_type resolver_data]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just general remark, I don't require any change.

But I wonder why you used deftype and create object here. There is no polymorphism here, there are no performance concern, there is no need for encapsulation. I wonder why this is not just a plain map

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Firstly i've done this with maps, but code, based on types look little bit better. In some way this is style of encapsulation of the logic. Cause while you querying data you need know what resolving procedure have to do now, and if it not be based on types thus it should be special Map which probably need to had lambdas on top of it, that can be overwritten if user start to pass simple maps and expanding this interface. I think if you need to do that, you need probably another sort of abstraction that ment you have to rewrite parsing / resolving procedures in the QueryDSL, and better option is a make a clone of command.
From the debug perspective you got # string, what also gave you quicker path to analyze some debug state if you needed it. I meen the thinking about the unique type called "resolver" sounds naturally , so never need to analyze what sit inside of those object.

@SerhiiRI SerhiiRI merged commit 1870db8 into main Oct 29, 2025
1 check passed
@SerhiiRI SerhiiRI deleted the macro-fix-query-dsl branch October 29, 2025 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants