Query builder that works with all major databases? - php

I need to use a query builder that generates SQL statements containing placeholders.
It should:
Generate SQL statements containing placeholders(:placeHolder or ?)
Have no object mapping
Return the query as a string or similar
Work with all major databases(e.g. Oracle, MySQL)
I am thinking about something like this:
QueryBuilder::select(
'db' => 'MySQL'
'from' => 'users',
'fields' => array(
'user_id' => 'id'
),
'where' => array(
'AND' => array(
/**
* ...conditions...
*/
)
),
'ljoin' => array(
'Group' => array(
'from' => 'groups'
/**
* ...stuff...
*/
)
)
);
I looked into Doctrine2 but it needs object mapping. And a lot of initial configuration.
I looked into Doctrine2 DBAL and it does not handle INSERT queries.
Note: Queries are generated in development stage and saved as plain text for each supported database engine.
Thank you in advance.

Try the Doctrine 2 ORM Query builder very versatile and works with most DBMS systems more at http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html

An example is the Code Igniter Active Record, you can build querys like:
$this->db->select('field_one, field_two')
->from('mytable')
->where(array('field' => 'value', 'field' => 'value'))

Related

working with mongoDB and PHP (Laravel)

I'm working with mongoDB and PHP (Laravel) and finding alot of difficulties in executing the complex queries on PHP (Laravel), all queries working smoothly on mongo Booster but when I execute them on PHP (Laravel) it really gives me tough time. Can any one help me out how could I execute them like raw queries on PHP (Laravel).
Raw queries in Laravel
Sometimes you may need to use a raw expression in a query. These expressions will be injected into the query as strings, so be careful not to create any SQL injection points! To create a raw expression, you may use the DB::raw method:
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
Another Example
$result = DB => collection('PMS')->raw(function ($collection){
return $collection->aggregate(array(
array( '$match' => array( "PanelID" => "A00898" ) ),
array( '$project' => array( 'EventTS' => 1, 'MainsPower' => 1 ) ),
array(
'$unwind' => array(
'path' => "$MainsPower",
'includeArrayIndex' => "arrayIndex",
'preserveNullAndEmptyArrays' => true
)
),
array(
'$project' => array(
'_id' => 0,
'MainsPower' => 1,
'timestamp' => array(
"$add" => array(
"$EventTS",
array( "$multiply" => array( 60000, "$arrayIndex" ) )
)
)
)
)
));
});
Sometimes you may need to use a raw expression in a query. These expressions will be injected into the query as strings, so be careful not to create any SQL injection points! To create a raw expression, you may use the DB::raw method:
$result = DB::select(
DB::raw('your query here')
);
Reference
Yes answers given by other is right but raw queries performing in Laravel is not good practice. Then why you are using Laravel Framework. You should use eloquent because if you change the db like mysql instead of mongo you need not to change quires. That's the power of Eloquent ORM.

How are filters applied in Elastic Search?

In ES are filters applied before the query?
Say, for example, I am doing a really slow fuzzy search but I am only doing it on a small date range. For an example you can look below (PHP):
$res=$client->search(array('index' => 'main', 'body' => array(
'query' => array(
'bool' => array(
'should' => array(
array('wildcard' => array('title' => '*123*')),
)
)
),
'filter' => array(
'and' => array(
array('range' => array('created' => array('gte' => date('c',time()-3600), 'lte' => date('c',time()+3600))))
)
),
'sort' => array()
)));
Will the filter be applied before trying that slower search?
Logic would dictate that filters are run and then the query but I would like to be sure.
If you use the filtered-query, then filters will be applied before documents are scored.
This will generally speed things up quite a lot. However, the fuzzy query will still be using the input to build a larger query regardless of the filters.
When you use filter right on the search object, then the query will first run without respecting the filter, then documents will be filtered out of the hits - whereas facets will remain unfiltered.
Therefore, you should almost always use the filtered-query, at least when you are not using facets.

Creating complex conditions with CakePHPs paginate and containable behavior

I'm using the containable behavior to look at several tables.
$this->paginate = array(
'contain' => array(
'Co' => array('fields' => array('ref')),
'CoItemType' => array('fields' => array('name')),
'Casing' => array(
'fields' => array('id','barcode','CONCAT(plant_dot,size_dot,product_line_dot,production_week) as dot'),
'Customer' => array('fields' => array('company_name')),
)
)
);
This works as expected. However I am integrating this with jQuery datatables and the way dataTables passes over conditions it does not specifiy a field. So I'd like to do conditions outside of the contains like so...
'conditions' = array(
'OR' => array(
array("Table.field_name LIKE " => '%'.$parameter.'%'),
array("Table.field_name LIKE " => '%'.$parameter.'%'),
array("Table.field_name LIKE " => '%'.$parameter.'%')
)
)
Of course this is not possible since the containable behavior wants you to include the conditions under the tables key in the contain array. This is frustrating, does anyone have a solution or workaround around to this problem?
I am using CakePHP 2.x
Use Linkable Behavior as noted in comments.

CakePHP Paginate 2 models into 1 set of results

It feels like I've tried everything. I'm building a newsfeed of sorts from 2 data tables 'Spec' and 'Update'. Here is the CakePHP code.
// Setup pagination
$this->paginate = array(
'Spec' => array(
'fields' => array(
'Spec.id',
'Spec.name'
),
'limit' => 10,
'conditions' => array(
'Spec.car_id' => $id
),
'order' => array(
'Spec.created' => $orderSetting
)
),
'Update' => array(
'fields' => array(
'Update.id',
'Update.name'
),
'limit' => 10,
'conditions' => array(
'Update.car_id' => $id
),
'order' => array(
'Update.created' => $orderSetting
)
)
);
$updates = $this->paginate(array('Spec', 'Update'));
This is returning an SQL error.
SQL Error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Update' at line 1
The problem is this line - it only allows for one item?
$updates = $this->paginate(array('Spec', 'Update'));
eg.
$updates = $this->paginate('Spec');
Which, of course, isn't what I'm looking for.
Any help or direction much appreciated.
The paginate() function does not allow multiple Models as a parameter, as it is really only a proxy to the find() function (see docs). Your second parameter ('Update') will be treated as a condition for the find() call - which results in the SQL error.
You will need to create a find() call on one model, that returns all the data you want. You can include data from the other model using model relations and possibly the ContainableBehavior.
Another way would be two different find() operations and manually combining the results. But the you would also have to handle the pagination manually.

Cakephp loadModel bindmodel not working

I have hasMany Through table which is Chats table with Chat model and I'm using loadModel in User controller to load Chat model then ran below query to bindModel with Chat.user_id and User.id :
$this->loadModel('Chat');
$this->Chat->bindModel(array(
'belongsTo' => array(
'User' => array(
'foreignKey' => false,
'conditions' => array('Chat.user_id = User.id')
)
)
));
$lastChat = $this->Chat->find('all', array(
'conditions' => array(
'Chat.receiver_id' => $user_id['User']['id']
),
'order' => array('Chat.id DESC'),
'fields' => array(
'Chat.id',
'Chat.chat',
'Chat.user_id',
'Chat.receiver_id',
'Chat.read',
'Chat.created'
),
'group' => array('Chat.user_id')
));
I want to join those tables together but this does not seem to work in Cake way I tried with normal SQL query and it works fine.
What could be wrong here?
Have you tried setting the recursive property before the find? Eg:
$this->Chat->recursive = 3;
You may need to set this after $this->Chat->bindModel, but I am not sure if this will make a difference or not. You will also need to re-bind the User model before each find, if, for example, your find queries are run within a loop ...

Categories