Using OR in CodeIgniter Active Record's Delete Method - codeigniter

I need to be able to convert the following to Ci's active record delete method but I don't know how to use the OR in the delete statement. Could you please tell me how I'd do this correctly?
$this->db->query("DELETE FROM friend WHERE userid_friends = '{$userid}' AND friendId_friends = '{$targetedUserId}' OR userid_friends = '{$targetedUserId}' AND friendId_friends = '{$userid}' ");

I guess your trying this:
$this->db->query("DELETE FROM friend WHERE
( userid_friends = '{$userid}' AND friendId_friends = '{$targetedUserId}') OR
( userid_friends = '{$targetedUserId}' AND friendId_friends = '{$userid}') ");
(note the added parentheses for the two AND clauses)
But actually your not using CI's "DELETE" method just a query.
Using active record delete would be something like:
$this->db->where("userid_friends = '{$userid}' AND friendId_friends = '{$targetedUserId}'");
$this->db->or_where("userid_friends = '{$targetedUserId}' AND friendId_friends = '{$userid}'");
$this->db->delete('friend');
For debugging of complex queries I recommend you to use
echo $this->db->last_query();
As it shows you exactly how the final query was rendered by the Active record methods.

Related

No result in my result view of Quick watch but the result is under non-public members

in my query when i see quick watch, under the result it returns no result but when go through Non-Public members under source and result in view I see all my results,how can i access to them? and why its like this?im using PostgreSQL for my database
var test = (from t in db.v_vpn_gateway.AsEnumerable()
where t.turbine_id.ToString() == id
select new TurbineDvce
{
Comments = "VPN Gateway",
Description = string.Empty,
DeviceIP = t.vpn_gateway.ToString(),
DeviceType = t.device_type,
FirmwareVersion = string.Empty,
Model = t.model,
Password = string.Empty,
Phone = string.Empty,
Producer = t.producer,
PublicIP = t.vpn_public_ip.ToString(),
TurbineId = t.turbine_id.ToString(),
Username = string.Empty
});
Looks like you need to "Hydrate" the result. The way Linq works with Lazy Evaluation, really you are just getting a place holder back for the test variable, and the actual query will run when the test variable is used by other code. Since you have a "where" clause, you should be expecting back an IEnumerable, so you can add ToList() or ToArray() to the end of your query, which will force the query to run and store the list or array in your test variable. That should give you access to that data right after the query runs.

DHTMLX. How to query from a database for list Units?

now, i get list Units from Database:
var sections = scheduler.serverList("type");
scheduler.createUnitsView({
name:"unit",
property:"type",
list:sections
});
$list = new OptionsConnector($res, $dbtype);
$list->render_table("doctors","id","id(value),first_name(first_name),last_name(last_name),middle_name(middle_name),spec(spec),image(image)");
$scheduler = new schedulerConnector($res, $dbtype);
$scheduler->set_options("type", $list);
But i want some query from Database for this. No render all values from Databases, just result from "Select *******"
Is it possible? Render_sql? Thank you advance
you can use render_sql method for this:
$list = new OptionsConnector($res, $dbtype);
$list->render_sql(
"SELECT * FROM doctors WHERE someColumn > " .$list->sql->escape("someValue") . " AND anotherColumn < ". $list->sql->escape("anotherValue"),
"id",
"id(value),first_name(first_name),last_name(last_name),middle_name(middle_name),spec(spec),image(image)"
);
$scheduler = new schedulerConnector($res, $dbtype);
$scheduler->set_options("type", $list);
The first parameter takes the sql query, and the rest parameters are the same as in render_table.
Also note that connectors don't support parameterized queries, but you can use $connector->sql->escape method if you need to insert request values into the query

Reusing query with one less join in codeigniter?

Is there any smart way of reusing current query. I want to use same query EXCEPT from one join. See example below:
$this->db->distinct();
$this->db->select('outfit_main.*');
$this->db->join('outfit_products', 'outfit_main.id = outfit_products.outfit_id');
$this->db->join('product', 'outfit_products.product_id = product.id');
$this->db->join('favorite', 'favorite.product_id = outfit_products.product_id');
$check = $this->db->get('outfit_main')->result('OutfitModel');
if ($check === false) {
//How to - use above query
//EXCEPT from
//$this->db->join('favorite', 'favorite.product_id = outfit_products.product_id');
$check = $this->db->get('outfit_main')->result('OutfitModel');
}
With smart way I mean that I wouldn't have to reset whole query and create a whole new query.

Doctrine 1 allowing SQL Injection?

I found this code on a legacy app:
$salt = $this->generateSalt();
$new_pass_update = Doctrine_Query::create()
->update('User')
->set('password', '"'. $this->hash($newPass, $salt) .'"')
->set('salt', "sleep(10)") // $salt) <- I replaced this
->where('email = ?', array($mail))
->getDql();
die($new_pass_update);
I was shocked to see this Dql generated as output:
UPDATE User SET password = "3dbe00a167653a1aaee01d93e77e730e"
salt = sleep(10) WHERE email = ?
First of all, I didn't expect to see the quotation marks around the password value. I thougt that Doctrine would do that for me, so I tried the second argument without them, but I was shocked to see this Dql generated as output:
UPDATE User SET password = "3dbe00a167653a1aaee01d93e77e730e"
salt = sleep(10) WHERE email = ?
If I change ->getDql() for -> execute() that's exactly the query that is executed and the db sleeps for 10 seconds.
Why is doctrine behaving like this?
As Gumbo pointed out, the right API to use with Doctrine 1.* update syntax is:
$new_pass_update = Doctrine_Query::create()
->update('User')
->set('password', "?", $this->hash($newPass, $salt))
->set('salt', "?", $salt)
->where('email = ?', array($mail))
->execute();
so, the second argument should be "?" and the third one, the associated value.

Multiple rows update without select

An old question for Linq 2 Entities. I'm just asking it again, in case someone has came up with the solution.
I want to perform query that does this:
UPDATE dbo.Products WHERE Category = 1 SET Category = 5
And I want to do it with Entity Framework 4.3.1.
This is just an example, I have a tons of records I just want 1 column to change value, nothing else. Loading to DbContext with Where(...).Select(...), changing all elements, and then saving with SaveChanges() does not work well for me.
Should I stick with ExecuteCommand and send direct query as it is written above (of course make it reusable) or is there another nice way to do it from Linq 2 Entities / Fluent.
Thanks!
What you are describing isnt actually possible with Entity Framework. You have a few options,
You can write it as a string and execute it via EF with .ExecuteSqlCommand (on the context)
You can use something like Entity Framework Extended (however from what ive seen this doesnt have great performance)
You can update an entity without first fetching it from db like below
using (var context = new DBContext())
{
context.YourEntitySet.Attach(yourExistingEntity);
// Update fields
context.SaveChanges();
}
If you have set-based operations, then SQL is better suited than EF.
So, yes - in this case you should stick with ExecuteCommand.
I don't know if this suits you but you can try creating a stored procedure that will perform the update and then add that procedure to your model as a function import. Then you can perform the update in a single database call:
using(var dc = new YourDataContext())
{
dc.UpdateProductsCategory(1, 5);
}
where UpdateProductsCategory would be the name of the imported stored procedure.
Yes, ExecuteCommand() is definitely the way to do it without fetching all the rows' data and letting ChangeTracker sort it out. Just to provide an example:
Will result in all rows being fetched and an update performed for each row changed:
using (YourDBContext yourDB = new YourDBContext()) {
yourDB.Products.Where(p => p.Category = 1).ToList().ForEach(p => p.Category = 5);
yourDB.SaveChanges();
}
Just a single update:
using (YourDBContext yourDB = new YourDBContext()) {
var sql = "UPDATE dbo.Products WHERE Category = #oldcategory SET Category = #newcategory";
var oldcp = new SqlParameter { ParameterName = "oldcategory", DbType = DbType.Int32, Value = 1 };
var newcp = new SqlParameter { ParameterName = "newcategory", DbType = DbType.Int32, Value = 5 };
yourDB.Database.ExecuteSqlCommand(sql, oldcp, newcp);
}

Resources