zf2 How to var_dump the result of select - zend-framework2

I am trying to var_dump the result (only database rows) of select query.
I have a simple TableGateway (facotry service_manager)
public function shwoContactFormMessages)
{
$select = new Select();
$select->from(self::$tableName);
return $this->selectWith($select);
}
MY Controller:
public function fooAction()
{
$test = $this->contactFormTable->shwoContactFormMessages();
var_dump($test);
// This will show the results the column and it is working
while ($item = $test->current())
{
echo $item->messageFrom . "<br>";
}
return $view;
}
Result of var_dump($test):
object(Zend\Db\ResultSet\ResultSet)#327 (8) {
["allowedReturnTypes":protected]=>
array(2) {
[0]=>
string(11) "arrayobject"
[1]=>
string(5) "array"
}
["arrayObjectPrototype":protected]=>
object(ArrayObject)#302 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
["returnType":protected]=>
string(11) "arrayobject"
["buffer":protected]=>
NULL
["count":protected]=>
int(5)
["dataSource":protected]=>
object(Zend\Db\Adapter\Driver\Pdo\Result)#326 (8) {
["statementMode":protected]=>
string(7) "forward"
["resource":protected]=>
object(PDOStatement)#307 (1) {
["queryString"]=>
string(49) "SELECT `hw_contact_form`.* FROM `hw_contact_form`"
}
["options":protected]=>
NULL
["currentComplete":protected]=>
bool(false)
["currentData":protected]=>
NULL
["position":protected]=>
int(-1)
["generatedValue":protected]=>
string(1) "0"
["rowCount":protected]=>
int(5)
}
["fieldCount":protected]=>
int(8)
["position":protected]=>
int(0)
}
I would like to var_dump the database rows only instead of the above object.

This is because the ResultSet is designed to give you each item "On Demand" rather than loading them all at once, which can cause you to use huge amounts of memory if the resultset is large.
You can get the full resultset as an array of items if you need:
var_dump($test->toArray()):

Related

selec2 search - Return no results found message if a specific criteria didnt match

I am using select2 4.0.3 for search drop down. As per my understanding its default functionality is not to match with the start of entries the drop down have. So I have implemented the below given code
function matchStart(params, data) {
params.term = params.term || '';
if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) == 0) {
return data;
}
return false;
}
$("select").select2({
placeholder : "Input country name or select region",
matcher : function (params, data) {
return matchStart(params, data);
},
});
My problem is, the dropdown is not showing "No results found" message even if there is no matching results found. Can anyone help me on this.
Thanks in advance.
Try changing the return value of matchStart from false to null.
Also you can remove the extra function around the matcher argument. The result:
function matchStart(params, data) {
params.term = params.term || '';
if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) == 0) {
return data;
}
return null;
}
$("select").select2({
placeholder: "Input country name or select region",
matcher: matchStart
});

Throw error in Mongoid

Lets say i have this code:
map = %Q{
function() {
emit(this.name, { likes: this.likes });
}
}
reduce = %Q{
function(key, values) {
var result = { likes: 0 };
values.forEach(function(value) {
if(value.likes < 0){
#{Rails.logger.error "likes are negativ" }
}
result.likes += value.likes;
});
return result;
}
}
Band.where(:likes.gt => 100).map_reduce(map, reduce).out(inline: true)
As you can see I want to record an error if the value.likes are negativ:
#{Rails.logger.error "likes are negativ" }
But this Code is executed each time I run the aggregate and not when the likes are negativ.
What can I do to throw an error in the aggregate statement?
Lets just analyze the code. Firstly:
map = %Q{
function() {
emit(this.name, { likes: this.likes });
}
}
Here a string is assigned to a variable map. Please not the %Q{} is just another way of writing "". Former is another syntax to easily define strings which have a double quote. e.g.
# pretty
%Q{He said "You are awesome"}
# not so pretty
"He said \"You are awesome\""
Next there is:
reduce = %Q{
function(key, values) {
var result = { likes: 0 };
values.forEach(function(value) {
if(value.likes < 0){
#{Rails.logger.error "likes are negative" }
}
result.likes += value.likes;
});
return result;
}
}
Here another string is assigned to a variable reduce. #{Rails.logger.error "likes are negative" } is just a regular string interpolation logging an error and returning true. So above code is equivalent to:
Rails.logger.error "likes are negative"
reduce = %Q{
function(key, values) {
var result = { likes: 0 };
values.forEach(function(value) {
if(value.likes < 0){
true
}
result.likes += value.likes;
});
return result;
}
}
You see why the logging statement is executed every time.
Next there is:
Band.where(:likes.gt => 100).map_reduce(map, reduce).out(inline: true)
This is just a simple statement using mongoid to execute a map-reduce command on the mongo server, passing map and reduce functions constructed earlier.
Note that in above code, intention is to execute ruby code in a javascript reduce function. However that is not possible, as reduce function is being executed on mongodb server and cannot execute the logging statement.
One way to handle the situation could be to reduce to a hash like {likes: 0, negative_likes: 0}, incrementing negative_likes conditionally and logging error on receiving result.
PS: it might be a better idea to use aggregation framework instead of map-reduce.

Checking how many fields have changed upon saving a form

I am saving records in a transaction using symfony1.4 and Doctrine.
The rows inserted are coming from a CSV file which is updated regularly. I have already got a method that checks if the records in the CSV match that in the DB and do not insert.
What I'm ideally wanting to do though, is to set a user flash telling them how many rows have been updated whenever they import the CSV file.
$conn = ProductTable::getInstance()->getConnection();
$conn->beginTransaction();
try {
$row = 1;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if ($row > 1) {
$values = array(
'blah' => null
);
$obj= ProductTable::getInstance()->findOrCreateNewProduct(
$values['blah']
);
$obj->merge($values);
$obj->save($conn);
}
$row++;
}
$conn->commit();
} catch (Doctrine_Exception $e) {
$conn->rollback();
throw $e;
}
I'm wondering how I'd get these updated fields. Is it in the actions.class.php or is it in the actual form.class.php file?
Thanks
On the you can call a Doctrine_Record::getModified() which will give you an array of fields modified (with their values though that doesnt matter for you). Then you can call count on the returned array and keep a cumulative total outside your loop.
$conn = ProductTable::getInstance()->getConnection();
$conn->beginTransaction();
$nbModified = 0;
try {
$row = 1;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if ($row > 1) {
$values = array(
'blah' => null
);
$obj= ProductTable::getInstance()->findOrCreateNewProduct(
$values['blah']
);
$obj->merge($values);
$nbModified += count($obj->getModified());
$obj->save($conn);
}
$row++;
}
$conn->commit();
// return $nbModified or otherwise do something with it here
} catch (Doctrine_Exception $e) {
$conn->rollback();
// youre rolling back so just for consistency set $nbModified to zero
$nbModified = 0;
throw $e;
}

Symfony Doctrine Models for Entity Without Primary Keys

I'm working with a legacy database while re-building the web application. I want to use Symfony2.x which obviously has Doctrine as ORM.
I've around 50 (mysql) tables which has NO Primary Keys. When I try to generate models, it does not let me do and throw an exception with "No Primary Key on ... table".
Do I must have Primary Keys on tables to use Doctrine or is there any way around it?
Any help would be great.
Thanks.
Doctrine requires every entity class to have an identifier/primary key.
Take a look at this page: http://www.doctrine-project.org/docs/orm/2.0/en/reference/basic-mapping.html#identifiers-primary-keys
It is a requirement for Doctrine to have an identifier/primary key.
Take a look at this page: http://www.doctrine-project.org/docs/orm/2.0/en/reference/basic-mapping.html#identifiers-primary-keys
But there is a way to generate mappings and entities from tables that do not have a primary key. A table with no primary key is an unusual and bad database design but such a scenario exists in case of legacy databases.
Solution:
Note: All references below refer to Doctrine 2.0
1. Find the file DatabaseDriver.php (in Doctrine/ORM/Mapping/Driver/DatabaseDriver.php)
2. Find the method reverseEngineerMappingFromDatabase. Modify the code as stated below. The original code is:
private function reverseEngineerMappingFromDatabase()
{
if ($this->tables !== null) {
return;
}
$tables = array();
foreach ($this->_sm->listTableNames() as $tableName) {
$tables[$tableName] = $this->_sm->listTableDetails($tableName);
}
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($tables as $tableName => $table) {
/* #var $table \Doctrine\DBAL\Schema\Table */
if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = $table->getForeignKeys();
} else {
$foreignKeys = array();
}
$allForeignKeyColumns = array();
foreach ($foreignKeys as $foreignKey) {
$allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
}
if ( ! $table->hasPrimaryKey()) {
throw new MappingException(
"Table " . $table->getName() . " has no primary key. Doctrine does not ".
"support reverse engineering from tables that don't have a primary key."
);
}
$pkColumns = $table->getPrimaryKey()->getColumns();
sort($pkColumns);
sort($allForeignKeyColumns);
if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) {
$this->manyToManyTables[$tableName] = $table;
} else {
// lower-casing is necessary because of Oracle Uppercase Tablenames,
// assumption is lower-case + underscore separated.
$className = $this->getClassNameForTable($tableName);
$this->tables[$tableName] = $table;
$this->classToTableNames[$className] = $tableName;
}
}
}
The modified code is:
private function reverseEngineerMappingFromDatabase()
{
if ($this->tables !== null) {
return;
}
$tables = array();
foreach ($this->_sm->listTableNames() as $tableName) {
$tables[$tableName] = $this->_sm->listTableDetails($tableName);
}
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($tables as $tableName => $table) {
/* #var $table \Doctrine\DBAL\Schema\Table */
if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = $table->getForeignKeys();
} else {
$foreignKeys = array();
}
$allForeignKeyColumns = array();
foreach ($foreignKeys as $foreignKey) {
$allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
}
$pkColumns=array();
if ($table->hasPrimaryKey()) {
$pkColumns = $table->getPrimaryKey()->getColumns();
sort($pkColumns);
}
sort($allForeignKeyColumns);
if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) {
$this->manyToManyTables[$tableName] = $table;
} else {
// lower-casing is necessary because of Oracle Uppercase Tablenames,
// assumption is lower-case + underscore separated.
$className = $this->getClassNameForTable($tableName);
$this->tables[$tableName] = $table;
$this->classToTableNames[$className] = $tableName;
}
}
}
3. Find the method loadMetadataForClass in the same file. Modify the code as stated below.
Find the code stated below:
try {
$primaryKeyColumns = $this->tables[$tableName]->getPrimaryKey()->getColumns();
} catch(SchemaException $e) {
$primaryKeyColumns = array();
}
Modify it like this:
try {
$primaryKeyColumns = ($this->tables[$tableName]->hasPrimaryKey())?$this->tables[$tableName]->getPrimaryKey()->getColumns():array();
} catch(SchemaException $e) {
$primaryKeyColumns = array();
}
The above solution creates mappings(xml/yml/annotation) even for tables that don't have a primary key.

Criteria building in GORM

if (params.filters) {
def o = JSON.parse(params.filters);
def groupOp = o.groupOp
def fields = o.rules.field
def values = o.rules.data
def op = o.rules.op
println fields
println values
if(groupOp == "AND") {
fields.eachWithIndex {a, i ->
println op[i]
if(op[i].equals( "eq")) {
and{ eq(fields[i], values[i])}
}
if(op[i].equals("ne")) {
and{ ne(fields[i], values[i])}
}
if(op[i].equals("ge")) {
def valu = Double.valueOf( values[i]);
and{ ge(fields[i], valu)}
}
}
}
if(groupOp == "OR") {
fields.eachWithIndex {a, i ->
println op[i]
if(op[i].equals( "eq")) {
println 'eq';
or{ eq(fields[i], values[i])}
}
if(op[i].equals("ne")) {
println 'ne';
or{ ne(fields[i], values[i])}
}
if(op[i].equals("ge")) {
def valu = Double.valueOf( values[i]);
or{ ge(fields[i], valu)}
}
}
}
}
where params.filters is following JSON text.
{
"groupOp":"OR",
"rules":[
{
"field":"foo1",
"op":"le",
"data":"9.5"
},
{
"field":"foo2",
"op":"eq",
"data":"12345-123"
},
{
"field":"foo3",
"op":"cn",
"data":"IDM"
}
]
}
This data is coming from JQuery data grid.
Is there a better way of doing this?
In the code I have just listed only 3 operators, but in real I have 14 operations.
You can use String as Criteria operation, like:
A.withCriteria {
'eq' (id, 1)
}
so you might come to something like
A.withCriteria {
(groupOp) {
for (???) {
(op[i]) (fields[i], parsedVals[i])
}
}
}
Anyway you'll need to sanitize the web-submitted query for only allowed subset of operations. You don't want to receive end execute arbitrary sqlRestriction, right? :D So the code is going to be more complex then this anyway.
Note: wrapping and{} or or {} around single statement has no point, you need to put it around whole block of if-s.
I suggest that you have a look at the source code of the FilterPane plugin. Its service does essentially what you are doing and may give you some ideas for enhancements.

Resources