I am using rule Book to create rules a chain of rule as follows:
RuleBookBuilder.create()
.withResultType(Boolean.class)
.addRule(
RuleBuilder.create()
.withFactType(Double.class)
.withResultType(Boolean.class)
.when(facts -> facts.get("amount_gt").getValue() > new Double(600))
.then((facts, result) -> {
result.setValue(true);
System.out.println(result.getValue()); //1st print statement
})
.addRule()
....
.build())
NameValueReferableMap facts = new FactMap();
facts.setValue("amount_gt", new Double(700));
rule.run(facts);
System.out.println(rule.getResult()); //2nd print statement
The fist print statement prints true (as excepted), but the 2nd statement gives Optional.empty
Can some one tell me what could be wrong ?
You seem to chain the rules and the return of the outer rule you are not showing.
If you are trying to access the return on an inner rule, then you need to similarly chain the get() calls.
I would try to "unchain" the rules and see what that yields.
Related
I have a simple rust program that interacts with a PostgreSQL database.
The actual code is:
for row in &db_client.query("select magic_value from priv.magic_value();", &[]).unwrap()
{
magic_value = row.get("magic_value");
println!("Magic value is = {}", magic_value);
}
And.. it works. But I don't like it: I know this function will return one and only one value.
From the example I found, for example here: https://docs.rs/postgres/latest/postgres/index.html
and here: https://tms-dev-blog.com/postgresql-database-with-rust-how-to/
You always have a recordset to loop on.
Which is the clean way to call a function without looping?
query returns a Result<Vec<Row>, _>. You are already unwrapping the Vec, so you can just use it directly instead of looping. By turning the Vec into an owning iterator yourself, you can even easily obtain a Row instead of a &Row.
magic_value = db_client.query("select magic_value from priv.magic_value();", &[])
.unwrap() // -> Vec<Row>
.into_iter() // -> impl Iterator<Item=Row>
.next() // -> Option<Row>
.unwrap() // -> Row
.get("magic_value");
I am using Helidon DBClient transactions and have found myself in a situation where I end up with a list of Singles, List<Single<T>> and want to perform the next task only after completing all of the singles.
I am looking for something of equivalent to CompletableFuture.allOf() but with Single.
I could map each of the single toCompletableFuture() and then do a CompletableFuture.allOf() on top, but is there a better way? Could someone point me in the right direction with this?
--
Why did I end up with a List<Single>?
I have a collection of POJOs which I turn into named insert .execute() all within an open transaction. Since I .stream() the original collection and perform inserts using the .map() operator, I end up with a List when I terminate the stream to collect a List. None of the inserts might have actually been executed. At this point, I want to wait until all of the Singles have been completed before I proceed to the next stage.
This is something I would naturally do with a CompletableFuture.allOf(), but I do not want to change the API dialect for just this and stick to Single/Multi.
Single.flatMap, Single.flatMapSingle, Multi.flatMap will effectively inline the future represented by the publisher passed as argument.
You can convert a List<Single<T>> to Single<List<T>> like this:
List<Single<Integer>> listOfSingle = List.of(Single.just(1), Single.just(2));
Single<List<Integer>> singleOfList = Multi.just(listOfSingle)
.flatMap(Function.identity())
.collectList();
Things can be tricky when you are dealing with Single<Void> as Void cannot be instantiated and null is not a valid value (i.e. Single.just(null) throws a NullPointerException).
// convert List<Single<Void>> to Single<List<Void>>
Single<List<Void>> listSingle =
Multi.just(List.of(Single.<Void>empty(), Single.<Void>empty()))
.flatMap(Function.identity())
.collectList();
// convert Single<List<Void>> to Single<Void>
// Void cannot be instantiated, it needs to be casted from null
// BUT null is not a valid value...
Single<Void> single = listSingle.toOptionalSingle()
// convert Single<List<Void>> to Single<Optional<List<Void>>>
// then Use Optional.map to convert Optional<List<Void>> to Optional<Void>
.map(o -> o.map(i -> (Void) null))
// convert Single<Optional<Void>> to Single<Void>
.flatMapOptional(Function.identity());
// Make sure it works
single.forSingle(o -> System.out.println("ok"))
.await();
In the non reactive world the following code snippet is nothing special:
interface Enhancer {
Result enhance(Result result);
}
Result result = Result.empty();
result = fooEnhancer.enhance(result);
result = barEnhancer.enhance(result);
result = bazEnhancer.enhance(result);
There are three different Enhancer implementations taking a Result instance, enhancing it and returning the enhanced result. Let's assume the order of the enhancer calls matters.
Now what if these methods are replaced by reactive variants returning a Flux<Result>? Because the methods depend on the result(s) of the preceding method, we cannot use combineLatest here.
A possible solution could be:
Flux.just(Result.empty())
.switchMap(result -> first(result)
.switchMap(result -> second(result)
.switchMap(result -> third(result))))
.subscribe(result -> doSomethingWith(result));
Note that the switchMap calls are nested. As we are only interested in the final result, we let switchMap switch to the next flux as soon as new events are emitted in preceding fluxes.
Now let's try to do it with a dynamic number of fluxes. Non reactive (without fluxes), this would again be nothing special:
List<Enhancer> enhancers = <ordered list of different Enhancer impls>;
Result result = Result.empty();
for (Enhancer enhancer : enhancers) {
result = enhancer.enhance(result);
}
But how can I generalize the above reactive example with three fluxes to deal with an arbitrary number of fluxes?
I found a solution using recursion:
#FunctionalInterface
interface FluxProvider {
Flux<Result> get(Result result);
}
// recursive method creating the final Flux
private Flux<Result> cascadingSwitchMap(Result input, List<FluxProvider> fluxProviders, int idx) {
if (idx < fluxProviders.size()) {
return fluxProviders.get(idx).get(input).switchMap(result -> cascadingSwitchMap(result, fluxProviders, idx + 1));
}
return Flux.just(input);
}
// code using the recursive method
List<FluxProvider> fluxProviders = new ArrayList<>();
fluxProviders.add(fooEnhancer::enhance);
fluxProviders.add(barEnhancer::enhance);
fluxProviders.add(bazEnhancer::enhance);
cascadingSwitchMap(Result.empty(), fluxProviders, 0)
.subscribe(result -> doSomethingWith(result));
But maybe there is a more elegant solution using an operator/feature of project-reactor. Does anybody know such a feature? In fact, the requirement doesn't seem to be such an unusual one, is it?
switchMap feels inappropriate here. If you have a List<Enhancer> by the time the Flux pipeline is declared, why not apply a logic close to what you had in imperative style:
List<Enhancer> enhancers = <ordered list of different Enhancer impls>;
Mono<Result> resultMono = Mono.just(Result.empty)
for (Enhancer enhancer : enhancers) {
resultMono = resultMono.map(enhancer::enhance); //previousValue -> enhancer.enhance(previousValue)
}
return resultMono;
That can even be performed later at subscription time for even more dynamic resolution of the enhancers by wrapping the whole code above in a Mono.defer(() -> {...}) block.
In WordPress as you must already known, when using get_posts() or query_posts() or even WP_Query, it is not possible to order the returned posts by specifying a list of post ID in the order we want.
Instead we have to loop through the results and re-order them on the PHP side. This is a performance hit and a bad practice. Instead we should use built-in MySQL functions to retrieve the posts in the desired order upfront.
Thankfully there is the posts_orderby which can be used to specify a custom ORDERBY statement, like this:
// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);
// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
global $my_post_ids;
$orderby_statement = 'FIELD(ID, '.implode(',',$my_post_ids).')';
return $orderby_statement;
}
// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
However there is a problem with the above code, is that it will affect the order of all queries on the page! Including queries made by plugins, shortcodes, and so on.
Easy fix!
The simple way to fix this, is to apply the filter only one time, and remove it as soon as it is called, by putting a remove_filter() within the filter itself, so it is run only once:
// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);
// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
// Disable this filter for future queries!
remove_filter(current_filter(), __FUNCTION__);
global $my_post_ids;
$orderby_statement = 'FIELD(ID, '.implode(',',$my_post_ids).')';
return $orderby_statement;
}
// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
Because I set this filter just before my custom query, once I execute my custom query it should be filtered by the posts_orderby filter set above, which is then immediately disabled so it won't affect any future queries.
In theory, that's great, and it works great in most case scenarios!
An issue with WPML
However I have encountered a case when using the WPML plugin where this filter affects other queries than mine and causes errors. I believe the WPML plugin is creating a query of its own that is executed just before my own custom query, making my filter applies to the WPML query instead of mine!
Is there any possible way to add a check within the filter to make sure that it affects the correct query?
Thank you very much
Edit:
The fix for WPML
For information, while the accepted answer for this question is correct, it didn't solve the problem I was having with WPML. Here is how I fixed the WPML conflict:
// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);
// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
// Disable this filter for future queries!
remove_filter(current_filter(), __FUNCTION__);
global $my_post_ids, $wpdb;
$orderby_statement = 'FIELD('.$wpdb->base_prefix.'posts.ID, '.implode(',',$my_post_ids).')';
return $orderby_statement;
}
// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
This filter takes two parameters, $orderby and &$this. "this" being the WP_Query object. I'm not sure how to detect that WPML is making the call, but we can check that your call is the one being
made.
$my_post_ids = array(1,3,2);
add_filter( 'posts_orderby', 'my_custom_orderby', 10, 2 );
function my_custom_orderby( $orderby_statement, $object )
{
global $my_post_ids;
if( $my_post_ids != $object->query['post__in'] )
return $orderby_statement;
// Disable this filter for future queries!
remove_filter( current_filter(), __FUNCTION__ );
$orderby_statement = 'FIELD(ID, ' . implode( ',', $my_post_ids ) . ')';
return $orderby_statement;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
is object empty?
update: (id, data) ->
toUpdate = #find(id)
if toUpdate isnt {}
console.log "hi mom"
console.log toUpdate
toUpdate.setProperty(key, value) for own key, value of data
return toUpdate
find:(id) ->
result = record for record in #storage when record.id is id
return result or {}
Given the following Mocha tests
describe '#update', ->
it 'should return an updated record from a given id and data when the record exists', ->
boogie = createData()
archive = new Archive("Dog")
dog = archive.create(boogie)
result = archive.update(1, {name:"Chompie", age:1})
result.name.should.eql "Chompie"
result.age.should.eql 1
result.emotion.should.eql dog.emotion
it 'should return an updated record from a given id and data when the record does not exist', ->
boogie = createData()
archive = new Archive("Dog")
dog = archive.create(boogie)
result = archive.update(50, {name:"Chompie", age:1})
result.should.not.exist
The result is
Archive #update should return an updated record from a given id and data when the record exists: hi mom
{ id: 1,
validationStrategies: {},
name: 'Boogie',
age: 2,
emotion: 'happy' }
✓ Archive #update should return an updated record from a given id and data when the record exists: 1ms
Archive #update should return empty when the record does not exist: hi mom
{}
✖ 1 of 13 tests failed:
1) Archive #update should return empty when the record does not exist:
TypeError: Object #<Object> has no method 'setProperty'
...surprising, isnt it?
CoffeeScript's is (AKA ==) is just JavaScript's === and isnt (AKA !=) is just JavaScript's !==. So your condition:
if toUpdate isnt {}
will always be true since toUpdate and the object literal {} will never be the same object.
However, if #find could return a known "empty" object that was available in a constant, then you could use isnt:
EMPTY = {}
find: ->
# ...
EMPTY
and later:
if toUpdate isnt EMPTY
#...
For example, consider this simple code:
a = { }
b = { }
console.log("a is b: #{a is b}")
console.log("a isnt b: #{a isnt b}")
That will give you this in your console:
a is b: false
a isnt b: true
But this:
class C
EMPTY = { }
find: -> EMPTY
check: -> console.log("#find() == EMPTY: #{#find() == EMPTY}")
(new C).check()
will say:
#find() == EMPTY: true
Demo: http://jsfiddle.net/ambiguous/7JGdq/
So you need another way to check if toUpdate isn't empty. You could count the properties in toUpdate:
if (k for own k of toUpdate).length isnt 0
or you could use the special EMTPY constant approach outlined above. There are various other ways to check for an empty object, Ricardo Tomasi has suggested a few:
Underscore offers _.isEmpty which is basically the for loop approach with some special case handling and a short circuit.
Underscore also offers _.values so you could look at _(toUpdate).values().length. This calls map internally and that will be the native map function if available.
You could even go through JSON using JSON.stringify(toUpdate) is '{}', this seems a bit fragile to me and rather round about.
You could use Object.keys instead of the for loop: Object.keys(toUpdate).length isnt 0. keys isn't supported everywhere though but it will work with Node, up-to-date non-IE browsers, and IE9+.
Sugar also has Object.isEmpty and jQuery has $.isEmptyObject.
A short-circuiting for loop appears to be the quickest way to check emptiness:
(obj) ->
for k of toUpdate
return true
false
That assumes that you don't need own to avoid iterating over the wrong things. But given that this is just a test suite and that an emptiness test almost certainly won't be a bottle neck in your code, I'd go with whichever of Underscore, Sugar, or jQuery you have (if you need portability and have to deal with the usual browser nonsense), Object.keys(x).length if you know it will be available, and (k for own k of toUpdate).length if you don't have the libraries and have to deal with browser nonsense and aren't certain that toUpdate will be a simple object.