Woking with DB in zend frameword 2 - zend-framework2

I'm a new guy in zend framework 2.
I'm try to work with zend db but I got a problem:
Ex: I have a table users
1 | email1 | passwod1
2 | email2 | passwod2
3 | email3 | passwod3
4 | email4 | passwod4
Now I want to get 'only' password with ID = 2 (SELECT 'password' FROM users WHERE id = 2).
How can I do it?

Try this in your model (UserTable class) :
$select = new \Zend\Db\Sql\Select('users');
$select->where(array('id'=>2));
$select->columns(array('password'));
$resultSet = $this->tableGateway->selectWith ( $select );
$yourRow = $resultSet->current();
See Reference

You can write your manual query and can execute as below, for that you have to use TableGateway(I hope you are using TableGateway for manipulating table data):
$sql="SELECT 'password' FROM users WHERE id = 2"; // Make sure your query will not raise any error.
$resultSet = $this->tableGateway->adapter->query($sql, \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
return $resultSet;

Related

How to execute an update on multiple rows using Linq Lambda Expression in ASP.Net MVC?

I'm having a hard time trying to execute an update on multiple rows in a table.
I've tried this code:
PayoutEntities payoutdb = new PayoutEntities();
public void SaveStatusBatch(string batchid)
{
payout_transaction data = payoutdb.payout_transaction.Where(x => x.batchid == batchid).FirstOrDefault();
data.status = "Success";
payoutdb.SaveChanges();
}
But it only updates only a single row where the batchid is a match to what is indicated in the parameter. I'm using Èntity Framework in this.
This is how my table looks like:
|batchid|name|status|
|1 |John| |
|1 |Nick| |
|1 |Bill| |
|2 |Ara | |
I wanted to update the status of John,Nick and Bill to Success.
Do you have any suggestions on how am i supposed to do this?
The concept is to change all the data and then call the SaveChanges of the DBContext object. e.g.:
public void SaveStatusBatch(string batchid)
{
payout_transaction data = payoutdb.payout_transaction
.Where(x => x.batchid == batchid)
.ToList();
data.ForEach(a=> a.status = "Success");
payoutdb.SaveChanges();
}

Distinct table using Entity Framework

I have a table like this:
+----+-------+------------------+
| ID | Name | TipoContenedorID |
+----+-------+------------------+
| 1 | first | 10 |
| 2 | two | 9 |
| 3 | three | 10 |
+----+-------+------------------+
So depending of "TipoContenedorID" I get the name of another table with anonymous type like this:
var vehiculo = _pService.Listar(x => x.TipoContenedor.CatalogosID.Equals("TCO"), includeProperties: "TipoContenedor").Select(x => new
{
x.TipoContenedor.ID,
x.TipoContenedor.Nombre
});
Problem is I just want to receive value one time. Actually I get:
TipoContenedor.Nombre = firstname
TipoContenedor.Nombre= secondname
TipoContenedor.Nombre = firstname
So I'm getting the first name twice. How do I distinct that TipoContenedorID if repeated just pass it? Regards
Add .Distinct()
var vehiculo = _pService
.Listar(x => x.TipoContenedor.CatalogosID.Equals("TCO"), includeProperties: "TipoContenedor")
.Select(x => new
{
x.TipoContenedor.ID,
x.TipoContenedor.Nombre
})
.Distinct();

Query builder with select

I am trying to select some columns from a join result. The query is:
$queryBuilder = new \Phalcon\Mvc\Model\Query\Builder();
$queryBuilder->columns(array('L.*', 'S.build_id'));
$queryBuilder->addFrom('Gadwin\Models\Licenses', 'L');
$queryBuilder->join('Gadwin\Models\Serials', 'S.id = L.serial_id', 'S');
$resultset = $queryBuilder->getQuery()->execute();
If i remove the columns method, the query works and return a Licenses collection. But, if i set the columns method, an empty array is returned.
Any ideas ?
Instead of query builder, try raw sql in phalcon.
create one method in your model.
public function myRawSql()
{
$query = "SELECT * FROM your_table WHERE some_condition";
$modelObj = new ModelName(); // Create object of your model
return $modelObj->getReadConnection()->query($query)->fetchAll();
}
I see that you ask for results from 2 Tables. In this case, Phalcon will return a ComplexResultSet, instead of a ResultSet. Try a get_class on your $resultset, and if it is a ComplexResultSet, you can iterate it to access its rows. It should be something like:
----------------------------------
| Licence (object) | s.id (int ) |
----------------------------------
| Licence (object) | s.id (int ) |
----------------------------------
Generally, try also using a debugging tool such as Kint to examine your variables. It can be very helpful.

Linq query with count (extension method)

I expect a very simple solution, but I can't for the life of me figure this out...
I am trying to create the LINQ equivalent of this:
SELECT Group, COUNT(*) as GroupCount
FROM table1
WHERE Valid > 0
GROUP BY Group, Project
I have this so far:
var model = _db.table1
.Where(r => r.Valid > 0)
.GroupBy(r => new { r.GROUP, r.Project})
.Select(r => new{ r.GROUP, GroupCount = r.count()};
What is wrong with my query? Visual studio throws and error stating that:
System.Linq.IGrouping' does not contain a definition for 'GROUP' and no extension method 'GROUP' accepting a first argument of type 'System.Linq.IGrouping' could be found (are you missing a using directive or an assembly reference?)
EDIT: Just a note: The above error is given for r.Group in the Select clause.
It also throws an error stating that the count extension method doesn't exist, but I've seen other examples done this way. Maybe I was looking at an example from an old version of LINQ?
EDIT2: Some example data
GroupName ProjectID Step Other Info...
-----------------------------------------------
GroupA | 1 | 1 | ..............
GroupA | 1 | 2 |..............
GroupA | 3 | 1 | ..............
GroupB | 4 | 1 | ..............
GroupB | 5 | 1 | ..............
GroupC | 6 | 1 |..............
Desired result:
GroupName Group Count
---------------------------
GroupA | 2
GroupB | 2
GroupC | 1
Well, you have following errors in the .Select statement:
.count should be .Count (C# is case sensitive)
r.GROUP should be r.Key or r.Key.GROUP (.GroupBy() returns an IGrouping<TKey, TElement>)
You forgot the last parenthesis in the Select method. (But maybe that was just a typo in the example)
Result:
var model = _db.table1
.Where(r => r.Valid > 0)
.GroupBy(r => new { r.GROUP, r.Project })
.Select(r => new { r.Key.GROUP, GroupCount = r.Count() });
UPDATE:
After the comments and question update; it looks like you are only grouping by group, so that would turn in to something like this to yield the output you requested:
var model = _db.table1
.Where(r => r.Valid > 0)
.GroupBy(r => new { r.GROUP }) // First, group only on GROUP
.Select(r => new
{
r.Key.GROUP,
// Second, group on unique ProjectId's
GroupCount = r.GroupBy(g => g.Project).Count()
});
Or simplified:
var model = _db.table1
.Where(r => r.Valid > 0)
.GroupBy(r => r.GROUP) // First, group only on GROUP
.Select(r => new
{
Group = r.Key,
// Second, group on unique ProjectId's
GroupCount = r.GroupBy(g => g.Project).Count()
});
As you asked in the comments, yes, you could say that the values are concatenated in the GroupBy clause. So new { r.GROUP, r.Project } would group all pairs with the same value.
LINQ queries are case-sensitive. You're trying to access r.GROUP, which probably doesn't exist. Use r.Group instead. Also change r.count() to r.Count(). Here's the corrected code:
var model = _db.table1
.Where(r => r.Valid > 0)
.GroupBy(r => new { r.Group, r.Project})
.Select(r => new{ r.Key, GroupCount = r.Count()};
When you're doing the Group By, you're creating a new anonymous type (not of the type you think it is). Thus, when you're doing the select statement, it has no idea what the heck GROUP is.
To mitigate this, follow the 2nd answer located here.

grails: converting SQL into domain classes

I am developing a GRAILS application (I'm new to GRAILS and inherited the project from a previous developer). I'm slowly getting a small grasp for how GRAILS operates and the use of DOMAIN classes, hibernate etc. The MySQL db is hosted on Amazon and we're using ElasticCache.
Do any of you more knowledgeable folks know how I can go about converting the following SQL statement into domain classes and query criteria.
if(params?.searchterm) {
def searchTerms = params.searchterm.trim().split( ',' )
def resultLimit = params.resultlimit?: 1000
def addDomain = ''
if (params?.domainname){
addDomain = " and url like '%${params.domainname}%' "
}
def theSearchTermsSQL = ""
/*
* create c.name rlike condition for each search term
*
*/
searchTerms.each{
aSearchTerm ->
if( theSearchTermsSQL != '' ){
theSearchTermsSQL += ' or '
}
theSearchTermsSQL += "cname rlike '[[:<:]]" + aSearchTerm.trim() + "[[:>:]]'"
}
/*
* build query
*
*/
def getUrlsQuery = "select
u.url as url,
c.name as cname,
t.weight as tweight
from
(category c, target t, url_meta_data u )
where
(" + theSearchTermsSQL + ")
and
t.category_id = c.id
and t.url_meta_data_id = u.id
and u.ugc_flag != 1 " + addDomain + "
order by tweight desc
limit " + resultLimit.toLong()
/*
* run query
*
*/
Sql sqlInstance = new Sql( dataSource )
def resultsList = sqlInstance.rows( getUrlsQuery )
}
The tables are as follows (dummy data):
[Category]
id | name
-----------
1 | small car
2 | bike
3 | truck
4 | train
5 | plane
6 | large car
7 | caravan
[Target]
id | cid | weight | url_meta_data_id
----------------------------------------
1 | 1 | 56 | 1
2 | 1 | 76 | 2
3 | 3 | 34 | 3
4 | 2 | 98 | 4
5 | 1 | 11 | 5
6 | 3 | 31 | 7
7 | 5 | 12 | 8
8 | 4 | 82 | 6
[url_meta_data]
id | url | ugc_flag
---------------------------------------------
1 | http://www.example.com/foo/1 | 0
2 | http://www.example.com/foo/2 | 0
3 | http://www.example.com/foo/3 | 1
4 | http://www.example.com/foo/4 | 0
5 | http://www.example.com/foo/5 | 1
6 | http://www.example.com/foo/6 | 1
7 | http://www.example.com/foo/7 | 1
8 | http://www.example.com/foo/8 | 0
domain classes
class Category {
static hasMany = [targets: Target]
static mapping = {
cache true
cache usage: 'read-only'
targetConditions cache : true
}
String name
String source
}
class Target {
static belongsTo = [urlMetaData: UrlMetaData, category: Category]
static mapping = {
cache true
cache usage: 'read-only'
}
int weight
}
class UrlMetaData {
String url
String ugcFlag
static hasMany = [targets: Target ]
static mapping = {
cache true
cache usage: 'read-only'
}
static transients = ['domainName']
String getDomainName() {
return HostnameHelper.getBaseDomain(url)
}
}
Basically, a url from url_meta_data can be associated to many categories. So in essence what I'm trying to achieve should be a relatively basic operation...to return all the urls for the search-term 'car', their weight(i.e importance) and where the ugc_flag is not 1(i.e the url is not user-generated content). There are 100K + of records in the db and these are imported from a third-party provider. Note that all the URLs do belong to my client - not doing anything dodgy here.
Note the rlike I've used in the query - I was originally using ilike %searchterm% but that would find categories where searchterm is part of a larger word, for example 'caravan') - unfortunately though the rlike is not going to return anything if the user requests 'cars'.
I edited the code - as Igor pointed out the strange inclusion originally of 'domainName'. This is an optional parameter passed that allows the user to filter for urls of only a certain domain (e.g. 'example.com')
I'd create an empty list of given domain objects,
loop over the resultsList, construct a domain object from each row and add it to a list of those objects. Then return that list from controller to view. Is that what you're looking for?
1) If it's a Grails application developed from a scratch (rather than based on a legacy database structure) then you probably should already have domain classes Category, Target, UrlMetaData (otherwise you'll have to create them manually or with db-reverse-engineer plugin)
2) I assume Target has a field Category category and Category has a field UrlMetaData urlMetaData
3) The way to go is probably http://grails.org/doc/2.1.0/ref/Domain%20Classes/createCriteria.html and I'll try to outline the basics for your particular case
4) Not sure what theDomain means - might be a code smell, as well as accepting rlike arguments from the client side
5) The following code hasn't been tested at all - in particular I'm not sure how disjunction inside of a nested criteria works or not. But this might be suitable a starting point; logging sql queries should help with making it work ( How to log SQL statements in Grails )
def c = Target.createCriteria() //create criteria on Target
def resultsList = c.list(max: resultLimit.toLong()) { //list all matched entities up to resultLimit results
category { //nested criteria for category
//the following 'if' statement and its body is plain Groovy code rather than part of DSL that translates to Hibernate Criteria
if (searchTerms) { //do the following only if searchTerms list is not empty
or { // one of several conditions
for (st in searchTerms) { // not a part of DSL - plain Groovy loop
rlike('name', st.trim())) //add a disjunction element
}
}
}
urlMetaData { //nested criteria for metadata
ne('ugcFlag', 1) //ugcFlag not equal 1
}
}
order('weight', 'desc') //order by weight
}
Possibly the or restriction works better when written explicitly
if (searchTerms) {
def r = Restrictions.disjunction()
for (st in searchTerms) {
r.add(new LikeExpression('name', st.trim()))
}
instance.add(r) //'instance' is an injected property
}
Cheers,
Igor Sinev

Resources