QueryBuilder alias for expr() in select() method - doctrine-orm

is there any option to set alias for $qb->expr()->avg('e.value') in select() method of Doctrine2 query builder?
I have e.g. this query:
$qb->select($qb->expr()->avg('e.value'), 'e someAlias')->from('Entity', 'e');
But the average value is indexed by integer in the result, like this:
array(
0 => array(
'someAlias' => Entity {},
1 => 2.5255,
),
);
Is it possible to change key of the average value to the defined string value?

Try the following to set the alias:
$qb->select(array(
$qb->expr()->select()->avg('e.value').' AS aveAlias')
,'e someAlias')
)->from('Entity', 'e');

Related

How to remove double quotes from keys in RDD and split JSON into two lines?

I need to modify the data to give input to CEP system, my current data looks like below
val rdd = {"var":"system-ready","value":0.0,"objectID":"2018","partnumber":2,"t":"2017-08-25 11:27:39.000"}
I need output like
t = "2017-08-25 11:27:39.000
Check = { var = "system-ready",value = 0.0, objectID = "2018", partnumber = 2 }
I have to write RDD map operations to achieve this if anybody suggests better option welcome. colcount is the number of columns.
rdd.map(x => x.split("\":").mkString("\" ="))
.map((f => (f.dropRight(1).split(",").last.toString, f.drop(1).split(",").toSeq.take(colCount-1).toString)))
.map(f => (f._1, f._2.replace("WrappedArray(", "Check = {")))
.map(f => (f._1.drop(0).replace("\"t\"", "t"), f._2.dropRight(1).replace("(", "{"))) /
.map(f => f.toString().split(",C").mkString("\nC").replace(")", "}").drop(0).replace("(", "")) // replacing , with \n, droping (
.map(f => f.replace("\" =\"", "=\"").replace("\", \"", "\",").replace("\" =", "=").replace(", \"", ",").replace("{\"", "{"))
Scala's JSON parser seems to be a good choice for this problem:
import scala.util.parsing.json
rdd.map( x => {
JSON.parseFull(x).get.asInstanceOf[Map[String,String]]
})
This will result in an RDD[Map[String, String]]. You can then access the t field from the JSON, for example, using:
.map(dict => "t = "+dict("t"))

Pass data variable to function when Unit Testing

I am new to unit testing in PHP and I'm having a little trouble. Whether that is because I'm using the Cake framework or because I'm used to the Java way, point it I'm having issues.
I'm writing tests for a Model function that gets called on the submit of a form. The function receives two parameters, which I think I'm passing through correctly, and a data object that is not received as a parameter. My question is how do I populate that "data" object? I keep getting and "undefined index" error when I run the tests.
I've tried both mocking the data and using fixtures, but in all honesty, I don't get this stuff. Below is my model function, followed by my test code.
public function isUniqueIfVerified($check, $unverified){
$found = false;
if ($this->data['Client']['client_type_id'] == 5) {
$found = $this->find ( 'first', array (
'conditions' => array (
$check,
$this->alias . '.' . $this->primaryKey . ' !=' => $this->id,
'client_type_id <>' => 5
),
'fields' => array (
'Client.id'
)
) );
} else {
$found = $this->find ( 'first', array (
'conditions' => array (
$check,
$this->alias . '.' . $this->primaryKey . ' !=' => $this->id
),
'fields' => array (
'Client.id'
)
) );
}
if ($found) {
return false;
} else {
return true;
}
}
This is like the 52 version of my test function, so feel free to just do whatever you want with it. I was thinking that mocking the data would be easier and faster, since I only really need the 'client_type_id' for the condition inside my Model function, but I couldn't get that 'data' object to work, so I switched to fixtures... with no success.
public function testIsUniqueIfVerified01() {
$this->Client = $this->getMock ( 'Client', array (
'find'
) );
$this->Client->set(array(
'client_type_id' => 1,
'identity_no' => 1234567890123
));
//$this->Client->log($this->Client->data);
$check = array (
'identity_no' => '1234567890123'
);
$unverified = null;
$this->Client = $this->getMockforModel("Client",array('find'));
$this->Client->expects($this->once())
->method("find")
->with('first', array (
'conditions' => array (
"identity_no" => "1234567890123",
"Client.id" => "7711883306236",
'client_type_id <>' => 5
),
'fields' => array (
'Client.id'
)
))
->will($this->returnValue(false));
$this->assertTrue($this->Client->isUniqueIfVerified($check, $unverified));
unset ( $this->Client );
}
Again, I'm very green when it comes to Cake, and more specifically PHP Unit Testing, so feel free to explain where I went wrong.
Thanks!
You'll need to make a slight adjustment to your model function (which I'll show below) but then you should be able to do something like this to pass through data in the data object:
$this->Client->data = array(
'Client' => array(
'client_type_id' => 5,
'identity_no' => 1234567890123
));
This is instead of the "set" you used, as below:
$this->Client->set(array( ...
Also, you mocked the Client model, then "set" a few things, but then just before you do the test, you mock it again. This means you're throwing away all the thins you set for the mock you did right at the top. You can do something as below which should solve you problem:
public function testIsUniqueIfVerified01() {
$this->Client = $this->getMock ( 'Client', array (
'find'
) );
$this->Client->data = array(
'Client' => array(
'client_type_id' => 5,
'identity_no' => 1234567890123
));
$check = array (
'identity_no' => '1234567890123'
);
$unverified = null;
$this->Client->expects($this->once())
->method("find")
->with($this->identicalTo('first'), $this->identicalTo(array(
'conditions' => array (
$check,
"Client.id !=" => 1,
'client_type_id <>' => 5
),
'fields' => array (
'Client.id'
)
)))
->will($this->returnValue(false));
$this->assertTrue($this->Client->isUniqueIfVerified($check, $unverified));
unset ( $this->Client );
}
This should at least give you an idea of what to do. Hope it helps!

doctrine2 get rows from mapping table

I am trying to get the mapping table associated ids.
mapping_table
id service_receiver_id service_provider_id
1 1 2
2 4 1
How can i write the doctrine query for retrieving 1 mapped to...
i need the results like,
associated_with
2
4
In my case i have using this query:
$qb->select('om', 'o', 'ot')
->from('Organization\Entity\OrgMapping', 'om')
->leftJoin('om.organization', 'o')
->where('om.organization = :hspId')
->setParameter('hspId', $hspId);
above query result only
//List of Associates that is Mapped Already
$organizations = $this->orgMappingRepository->listAssociatesByHSPId($hspId, $mapType, $filterBy, $searchBy, $pageNo, $paginationArr);
$mappedAssociates = array();
foreach ($organizations as $org) {
$mappedAssociates[$org->getServiceProvider()->getId()] = array(
'id' => $org->getServiceProvider()->getId(),
'name' => $org->getServiceProvider()->getName(),
'orgType' => $org->getServiceProvider()->getOrgType()->getName(),
'logo' => $org->getServiceProvider()->getLogo(),
'cityName' => $org->getServiceProvider()->getCity() ? $org->getServiceProvider()->getCity()->getName() : null,
'areaName' => $org->getServiceProvider()->getArea() ? $org->getServiceProvider()->getArea()->getName() : null,
'zipcode' => $org->getServiceProvider()->getZipcode(),
);
}
the result i am getting is :
id service_receiver_id service_provider_id
1 1 2

Faking an enumerator in FakeItEasy

How can I create a fake with FakeItEasy that allows different return values on successive calls. This is one example of what I would like to be able to do:
var enumerator = A.Fake<IDictionaryEnumerator>();
A.CallTo(() => enumerator.MoveNext()).Returns(true); //Expected value for first call
A.CallTo(() => enumerator.Key).Returns("key1");
A.CallTo(() => enumerator.Value).Returns("value1");
A.CallTo(() => enumerator.MoveNext()).Returns(false); //Expected value for second call
Assert.IsTrue(enumerator.MoveNext()); //Fails
Assert.IsFalse(enumerator.MoveNext());
The assertion will fail since it the last set up of MoveNext will overwrite the first one.
Is it possible to do what I want in FakeItEasy?
.
[Edit]
Clarified the original question's example and provided a working example below.
Based on Patrik's answer this code shows how you can set up the fake. The trick is to reverse all setups and use Once().
var enumerator = A.Fake<IDictionaryEnumerator>();
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
A.CallTo(() => enumerator.MoveNext()).Returns(true).NumberOfTimes(2);
A.CallTo(() => enumerator.Key).Returns("key2").Once();
A.CallTo(() => enumerator.Value).Returns("value2").Once();
A.CallTo(() => enumerator.Key).Returns("key1").Once();
A.CallTo(() => enumerator.Value).Returns("value1").Once();
while(enumerator.MoveNext())
{
Debug.WriteLine(enumerator.Key + ": "+ enumerator.Value);
}
This will print:
key1: value1
key2: value2
I'm not entirely sure that I understand what you mean, the code you supplied will always fail. However if you mean that you want it to return true the second time it's called it can be done. There are a couple of different ways that I can think of, two of them are:
A.CallTo(() => enumerator.MoveNext()).ReturnsNextFromSequence(false, true);
The other way is:
A.CallTo(() => enumerator.MoveNext()).Returns(true);
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
Edit:
On second though I guess I understand your question better, what you want to happen is that MoveNext should return true the first time and false the second time? If that's the case just change the orders of the values in the examples above.
FakeItEasy does not use a record/replay model and you are correct in that the latest configured rule has precedence over any earlier specified rules. That's why you have to specify repeat - ".Once()" - on the latest configuration for it only to be valid once.
There are many reasons why the latest has precedence, one of the most important ones is that it lets you set up a default return value in the setup of your fixture and override it to return specific values in some of your tests, this is impossible when using a record/replay model.
The OP's example based on Patrik's answer is fine ... but tedious if the sequence grows large. To supplement that answer consider that even though fake/mock examples most often show a bunch of straight line code to Arrange themselves you actually have the full power of a programming language at your command. Conditionals, loops, and even procedures.
So consider the following:
public static void AFakeDictionaryEnumeratorReturns(
IDictionaryEnumerator enumerator, params object[] pairs)
{
if (0 != pairs.Length % 2)
throw new ArgumentException("pairs must have even number of elements", "pairs");
int n = pairs.Length / 2;
A.CallTo(() => enumerator.MoveNext()).Returns(false).Once();
A.CallTo(() => enumerator.MoveNext()).Returns(true).NumberOfTimes(n);
for (int i = pairs.Length; i > 0; i -= 2)
{
A.CallTo(() => enumerator.Key).Returns(pairs[i - 2]).Once();
A.CallTo(() => enumerator.Value).Returns(pairs[i - 1]).Once();
}
}
and now the test becomes:
var enumerator = A.Fake<IDictionaryEnumerator>();
AFakeDictionaryEnumeratorReturns(enumerator,
"key1", "value1", "key2", "value2", "key3", "value3");
var keys = new List<object>();
var values = new List<object>();
while (enumerator.MoveNext())
{
keys.Add(enumerator.Key);
values.Add(enumerator.Value);
}
Assert.Equal(new List<object> { "key1", "key2", "key3" }, keys);
Assert.Equal(new List<object> { "value1", "value2", "value3" }, values);
(An IDictionaryEnumerator deals in pairs, so this example isn't as clearly beneficial as it could be. For a standard IEnumerator<T> a single static generic method would serve for a whole bunch of different enumerators.)

How create select/options tag from find('threaded') in CakePHP

How to create select/option html tag from find('threaded') data in CakePHP?
Function find() return results like this:
Array
(
[0] => Array
(
[Forum] => Array
(
[id] => 1
[name] => Forum
)
[children] => Array
(
[0] => Array
(
[Forum] => Array
(
[id] => 3
[name] => Programowanie
[parent_id] => 1
)
)
[1] => Array
(
[Thread] => Array
(
[id] => 11
[name] => Nowe forumowisko
[parent_id] => 1
)
)
)
)
[1] => Array
(
[Forum] => Array
(
[id] => 4
[name] => Nauka
[parent_id] => 0
)
[children] => Array
(
)
)
)
How?
there is a build in method for tree like results to be made into a list for select option tags:
$this->Model->generateTreeList($conditions, null, null, ' - ', $recursive);
instead of using find(threaded)
that is if you attached the Tree behavior to it (which you probably should have since its obviously a tree like model).
But if you want to keep your find(threaded) method you need to manually transform it via recursive method.
thanks DSkinner, very informative..
i have modified it to be more generic:
/**
* Returns an indented html select based on children depth
*
* #param array $data_array - Array of data passed in from cake's find('threaded') feature
* #param array $model - the model name
* #param array $key - the key field on the model
* #param array $value - the value field on the model
* #param array $list - Used internally, contains array to be returned
* #param int $counter - Used Internally, counter for depth
* #return array
*/
public function threaded_to_list($data_array, $model=null, $key='id', $value='name',
&$list = array(), $counter = 0, $separator='__')
{
if ( ! is_array($data_array))
return array();
foreach ($data_array AS $data)
{
$list[$data[$model][$key]] = str_repeat($separator, $counter).$data[$model][$value];
if ( ! empty($data['children']))
{
$this->threaded_to_list($data['children'], $model, $key, $value, $list, $counter + 1);
}
}
return $list;
}
Here's what worked for me.
Make sure you replace:
{SELECT_ID} with the value of the drop down
{SELECT_LABEL} with what is displayed as the option
{MODEL_NAME}
with your model name
/**
* Returns an indented html select based on children depth
*
* #param array $data_array - Array of data passed in from cake's find('threaded') feature
* #param array $list - Used internally, contains array to be returned
* #param int $counter - Used Internally, counter for depth
* #return array
*/
public function drop_down_from_threaded($data_array, &$list = array(), $counter = 0)
{
if ( ! is_array($data_array))
return array();
foreach ($data_array AS $data)
{
$list[$data[{SELECT_ID}]] = str_repeat(' ', $counter).$data[{SELECT_LABEL}];
if ( ! empty($data['children']))
{
$this->drop_down_from_threaded($data['children'], $list, $counter + 1);
}
}
return $list;
}
/**
* Get the data from the find('threaded') and pass it to our new function
*/
$results = $this->{MODEL_NAME}->find('threaded');
$results = $this->drop_down_from_threaded($results);
This may not work 100% for everyone, it works for me, but it should help give you something to start with.
What are "children"? Seems like your tree is spawned across one-to-many relations
It is not necessary to use the Tree behavior to use this method - but all desired results must be possible to be found in a single query.