Xquery: Selecting n number of records at a time - xquery

I'm using XQUERY, I have 25000 records saved in Database, I want to select these records in chunks(1000), How do I get the records recursively?

Window queries
You could use the tumbling window for this purpose, sadly it isn't supported by many XQuery engines yet.
For the following suggestions, you have to wrap the results into XML as XQuery only knows flat sequences, no nested ones.
Building your own tumbling windows
You can build your own tumbling windows functions which could look like this one, it creates "window" elements containing $count "item" elements each:
declare function local:window($seq as item()*, $size as xs:integer) as item()* {
for $i in 1 to xs:integer(fn:ceiling(count($seq) div $size))
return
element {"window"} {
for $j in (($i - 1) * $size + 1) to $i*$size
return
element {"item"} {$seq[$j]}
}
};
local:window((2, 4, 6, 8, 10, 12, 14), 3)
Splitting sequences for recursive windows
If you want to solve this problem recursively, you will need some split function which sadly isn't available in standard xquery. You could use $n=1000, work with the "head" elements and call your "worker function" recursively with the "tail".
declare function local:split($seq as item()*, $n as xs:integer) as element()* {
(
element {"head"} {
for $i in subsequence($seq, 1, $n)
return element {"item"} {$i}
},
element {"tail"} {
for $i in subsequence($seq, $n+1)
return element {"item"} {$i}
}
)
};
local:split((2, 4, 6, 8, 10, 12, 14), 3)
To access the tail elements as a sequence, use
local:split((2, 4, 6, 8, 10, 12, 14), 3)[2]//item/data()

Related

Builtin for checking if vec contains specified element

Let's say, I have a vec<int> containing a list of integers that may be non-continuous (due to element being removed from database).
Example:
$occupiedNumbers = vec[1, 2, 3, 5, 6, 8, 10, 11, 12, 13, 15, 16];
Now what I need is to check if this vec contains a given number, and if yes, increase it by 1 and repeat checking.
$newItemNumber = count($occupiedNumbers);
while (/* check if $occupiedNumbers contains $newItemNumber */) {
$a++;
}
In vanilla PHP there is in_array() for this, but would that work for a vec? Also, there is a builtin HH\Vector::linearSearch() but it's meant to be used with vec's predecessor, HH\Vector.
What is the right solution to check if a vec contains a given value?
Neither HHVM nor Hack docs say about that use case for a vec. Also, I'm missing some sort of REPL tool to check it manually off-project without building a whole (possibly faulty) project.
The recommendation from the HHVM/HackLang guys is to use C\contains() as you can read here but you need to install the HSL package (hhvm/hsl) using composer. This library contains loads of functions to deal with the new array-type structures: vec, dict, keyset. Those functions in the HSL Library are prefixed with C, Vec, Dict, Keyset and you'll find also Math, Str, etc., very useful for other needs.
After installing that package it becomes available but typically it is more handy to add use namespace to avoid the long prefix:
use namespace HH\Lib\C;
This is how you can do it:
$exists = C\contains($occupiedNumbers, $newItemNumber);
If you are really looking for the longest continuous interval starting from count($occupiedNumbers) then it may be much faster to find its initial index in the sorted list (if it exists), then use direct indexing from there:
// `use namespace HH\Lib\{C, Vec};` at top level
$occupiedNumbers = vec[1, 2, 3, 5, 6, 8, 10, 11, 12, 13, 15, 16];
$sorted = Vec\sort($occupiedNumbers); // if not sorted in general
$size = count($sorted);
$v = $size;
$i = C\find_key($sorted, $w ==> $w === $v);
if($i !== null) {
for(; $i < $size - 1 && $sorted[$i + 1] === $v + 1; $i++, $v++) {
}
}
// $i is null | <index of largest number in continuous interval>

writing an each & map method - array/ object iteration with object.prototype.toString

Trying to re-write each() & map()
this should be just like the native forEach, or the underscore or lodash _.each method. It should take an array or an object. I've heard conflicting things about whether or not to use Array.isArray or instanceof to determine if the collection passed in is an object or an array, and my current understanding is that using this object.prototype.toString thing is the best way. Maybe I'm completely wrong. I've been wacking away at this for hours, and would appreciate any suggestions or input at all.
My function seems to be okay, but it never makes any changes on any array or object I give it. If it is an object, I want to alter the values, not the property name. Sorry if my comments are annoyingly redundant. Please help.
TgEach( collection, callback )
Here are some stupid arrays and objects. For each, I am expecting the collection to be modified in place. Am I mistaken?
var tgObj = {one: 1, two: 2, three: 3, four: 4, five: 5 };
var tgArr = [ 1,2,3,4,5];
// I'm invoking it like
TgEach( tgObj, function(n){ return n + 3 } );
TgEach( tgArr, function(n){ return n + 3 } );
// I give it a collection and a callback - adding three to each item.
// I'm expecting `tgArr` to now equal `[4, 5, 6, 7, 8]` and
// `tgObj` to now equal `{ one: 4, two: 5, three: 6, four: 7, five: 8 };`
// But nothing ever happens...
// Here's my function...
var TgEach = function( collection, callback ){
var dataStructure = 0;
(function ObjectOrArray( collection ){
if ( {}.toString.call( collection ) === "[object Array]" ){
dataStructure += 1;
}
else if ( {}.toString.call( collection ) === "[object Object]" ){
dataStructure += 2;
}
})();
if ( dataStructure === 1 ){
for ( var i = 0; i < collection.length; i++ ){
callback( collection[i] );
}
else ( dataStructure === 2 ){
for ( var key in collection ){
callback( collection[key] );
}
}
};
for the callback function, let's say I want to add 3. So for this...
TgEach( tgObj, function(n){ return n + 3 } );
TgEach( tgArr, function(n){ return n + 3 } );
I'm expecting tgArr to now equal [4, 5, 6, 7, 8] and
tgObj to now equal
{ one: 4, two: 5, three: 6, four: 7, five: 8 };
But nothing ever happens...
TgMap( collection, callback )
map relies on each, so this has got me all stressed
my map looks like this..
var map = function( collection, callback ){
var result = [];
each( collection, function(item){
result.push( callback( collection[item] ) );
});
return result;
}
What the hell am I doing wrong here?

Variable scope in Sass for loops

In one of my SCSS scripts, I discovered that I had accidentally given a #for loop counter the same name as different, global variable, but everything still worked as expected.
For example, paste this example script into http://sassmeister.com/:
$w: white;
$r: red;
$b: blue;
$y: yellow;
//...
$test: '';
//Accidentally using an existing variable name ($r) as the counter:
#for $r from 1 through 10 {
#if($test != '') { $test: $test + ', '; }
$test: $test + $r;
}
.someclass {
/*Note: $r is 'red', not the #for counter. #for loops create their own scope?*/
color: $r;
/*All the #for counters. #for created a *local* $r, but accessed the *global* $test...*/
something: unquote($test);
}
...and the CSS will look like:
.someclass {
/*Note: $r is 'red', not the #for counter. #for loops create their own scope?*/
color: red;
/*All the #for counters. #for created a *local* $r, but accessed the *global* $test...*/
something: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
}
So, I would have thought that the #for loop changed $r from red to 10 by the time it was used in .someclass, but (luckily) it didn't. This indicates that the loop works in its own local scope, but it still accesses the global $test variable, even without using a !global flag.
And now I'm confused. The docs state that mixins have a local scope, but I haven't found any documentation about for loop scoping. Is this "hybrid" scoping a documented feature - the loop counter is in some local scope, while the loop "body" works in the parent scope - or is it a bug in the SCSS compiler?
I don't think this is a bug in the compiler as I believe this to be the intended behavior of the #for loop, but you're correct in that that it's not documented. I would submit a request to have this clarified / added into the official docs.

symfony get data from db in while loop

I need to grab data from a symfony 2 db. The data looks like :
Parent-Element [id 15]
-> Child Element [id 20, parent ID 15]
--->Child Element [id 27, parent ID 20]
----->Child Element [id 34, Parent ID 27]
....
The Childs are assigned to each parent Element by a cathegory ID see [ ].
There might be more than one Child Elements per level.
In php it would be easy to grab this by a while loop. But in Symfony im stucking. Can anyone help me finding a solution? IS there a while loop in symfony?
Kind regdards
Philipp
EDIT: I mean, in "normal" php I would do a simple while or create an array with ids which I loop through by another while loop... In smyfony, I would use a queryBuilder like that
$query = $em->createQueryBuilder()
->select('d')
->from('PrUserBundle:Location', 'd')
->where('d.client_id = :client_id')
->setParameter('client_id', $this->clientId)
->getQuery();
$results=$query->getResult();
Where I don't see any possibility to grab any other Ids or sort it so that I can render a parent-child listing.
What about iterators:
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach($iterator as $key => $value) {
echo "$key => $value\n";
}

Less mixin scope problems

I built a parametric mixin that finds the children of an element based on a "node-value" system that I created. What happens is the children are found by a loop function ".extractArrays" with ".deliverChild" inside it. Then the children (up to 4 of them) are put into ".calculateWidth", which returns the width of the child in a variable (ex. "calculatedWidth1").
The problem is: when there are no third and fourth children, #child3 and #child4 are unset, which creates an error. I set #child3 and #child4 to zero before the mixins, hoping that this would give them default values of 0 before the mixins are called. For some reason, however, when there is a third child, the mixin's returned value of #child3 won't override the #child3 that is set to 0. I am unsure why this is happening, but I feel like there are a couple things that throw me off about Less when it comes to mixins and scope.
#child3: none, 0 0, 0, 0;
#child4: none, 0 0, 0, 0;
.extractArrays(#index, #node, #node-value, #elements-array) when (#index <= #length-elements-array) {
#element-array: extract(#elements-array, #index);
#found-node: extract(#element-array, 2);
.deliverChild(#element-array, #found-node) when (#found-node = #child-node-value1) {
#child1: extract(#element-array, 1);
}
.deliverChild(#element-array, #found-node) when (#found-node = #child-node-value2) {
#child2: extract(#element-array, 1);
}
.deliverChild(#element-array, #found-node) when (#found-node = #child-node-value3) {
#child3: extract(#element-array, 1);
}
.deliverChild(#element-array, #found-node) when (#found-node = #child-node-value4) {
#child4: extract(#element-array, 1);
}
.deliverChild(#element-array, #found-node);
.extractArrays(#index + 1, #node, #node-value, #elements-array);
}
.extractArrays(1, #node, #node-value, #elements-array);
.calculateWidth(#child1, 1);
.calculateWidth(#child2, 2);
.calculateWidth(#child3, 3);
width: #calculatedWidth1 + #calculatedWidth2 + #calculatedWidth3 + #calculatedWidth4;
(Not an exact answer to the "scope" question above but an algorithm to use as a starting point in an alternative approach suggested in comments above):
A generic array filtering mixin would look like this (Less 1.7.5 or higher):
#array: // key value
a 1,
b 2,
c 3,
a 4,
d 5,
a 6,
c 7;
// usage:
usage {
.filter-array(#array, a);
result: #filter-array;
}
// impl.:
.filter-array(#array, #key, #key-index: 1) {
.-(length(#array));
.-(#i, #r...) when (#i > 0)
and not(#key = extract(extract(#array, #i), #key-index)) {
// skip item since key does not match
.-((#i - 1), #r);
}
.-(#i, #r...) when (length(#r) > 0)
and (#key = extract(extract(#array, #i), #key-index)) {
// key matches and #r is not empty so concat current item to #r
.-((#i - 1); extract(#array, #i), #r);
}
.-(#i, #r...) when (length(#r) = 0)
and (#key = extract(extract(#array, #i), #key-index)) {
// key matches and #r is empty so this is our first item
.-((#i - 1), extract(#array, #i));
}
.-(#i, #r...) when (#i = 0) {
// define "return" variable:
#filter-array: #r;
}
}
With resulting array being equal to:
#filter-array:
a 1,
a 4,
a 6;
This looks quite scary and verbose but still more clean and more controllable than the original approach.
Additionally it would make sense to provide a dedicated mixin to return a sum (or any other "transformation" with result in a single value) of certain values of the array items (that way the implementation can be simplified to a certain point since you won't need to concatenate anything and some of above conditions and/or mixin specializations become unnecessary).

Resources