When CodeIgniter is inserting a row into a DB, it doesn't encode PHP booleans into a form MySQL needs.
For example:
$new_record = array(
"name" => "Don",
"is_awesome" => true
);
This will enter into MySQL as this:
name (varchar) is_awesome (tinyint)
Don 0
Anyone know a good way to deal with this? I've been writing (is_awesome == true) ? 1 : 0; then setting the array value, but that sucks.
you can't add true or false to a TINYINT in mysql. you should do 1 or 0 like this
$new_record = array(
"name" => "Don",
"is_awesome" => 1 //1 means it's true
);
$query = $this->db->insert('table_name', $new_record);
then just when you fetch it consider 0 as false and 1 as true
Update:
you can create a function called tinyint_decode like this:
public function tinyint_decode($result = array(), $decode_set = array())
{
//$result is what you got from database after selecting
//$decode_set is what you would like to replace 0 and 1 for
//$decode_set can be like array(0=>'active', 1=>'inactive')
//after fetching the array
$result->is_awesome = ($result->is_awesome == 1 ? $decode_set[1] : $decode_set[0]);
return true;// or anything else
}
this way you can interpret 0 and 1 by anything you like whether it's true and false, active and inactive, or anything else just by passing $decode_set array.
MySQL doesn't have boolean values. What I usually do is:
1) Have a field of length char(1) and say 'Y' or 'N'
OR
2) Have a numeric field and say '1' or '0'
The one method to encode you mentioned is the only way to do it. If it's an extra step, I would just get rid of boolean in the PHP code itself and make it a '1-0' or 'Y-N'
Related
I have a search form with 4 inputs such as username, text, fromDate, toDate, and users can search with just one field , the problem is i don't know how to build a query with inputs which have values, I can compare them if each one of them has value or not like this :
if ($request->input('fromdatepicker') && $request->input('todatepicker') && $request->input('search-text')){
$query = \App\InstaPost::WhereFullTextWithTimestamp($request->input('search-text'), $from_timestamp, $to_timestamp)->paginate(12);
}else if ($request->input('search-text') && empty($request->input('fromdatepicker')) && empty($request->input('todatepicker'))){
$query = \App\InstaPost::WhereFullText($request->input('search-text'))->paginate(12);
} else if(empty($request->input('search-text')) && $request->input('fromdatepicker') && $request->input('todatepicker')){
$query = InstaPost::WhereTimestamp($from_timestamp, $to_timestamp)->paginate(12);
}
i have different scenarios:
as you can see so many scenarios,
but as you know it'll be a huge mess ! these if's is just for 3 inputs! and i should compare them for each scenarios , hope you understand the problem and help me.
I'm using Laravel-Mongodb(jessengers) and i should find out which input has value and then make a query and add them to this code block :
public function scopeWhereFullTextWithTimestamp($query,$search,$from_timestamp , $to_timestamp)
{
$query->getQuery()->projections = ['score'=>['$meta'=>'textScore']];
$query->orderBy('post.taken_at_timestamp','DESC');
return $query->whereRaw([
'$text' => ['$search' => $search],
'post.taken_at_timestamp'=> [
'$gte' => $from_timestamp,
'$lte' => $to_timestamp
]
]);
this is for search-text , fromDate and toDate inputs,
You can concatenate queries based on the input, something in this direction should do the trick.
$base_query = App\InstaPost;
if(!is_null($request->input('search-text'))){
$base_query->WhereFullText($request->input('search-text'));
}
if...
if..
$result = $base_query->get(); //or paginate()
TAB_XXX and TAB_XXX_details are one-to-many relationships, I need to query the two tables, however, we need to be filtered TAB_XXX_details。
The code is as follows:
var qu = from c in db.TAB_XXX.Where(n => n.DELETE_MARK == false)
let dets = c.TAB_XXX_DETAILS.Where(n => condition.SaleType.HasValue ? n.SALE_TYPE == (decimal)condition.SaleType : 1 == 1)
select new
{
c,
dets
};
Condition.SaleType is number?, if the condition.SaleType is a valid number, such as 1, 2, 3 ... I want to filter the child record based on these numbers; when the condition.SaleType is null, I want to query TAB_XXX and all its child records;
How do I modify the where clause?
Thank you for your answer!
Since 1 == 1 is always true, your condition boils down to this:
let dets = c.TAB_XXX_DETAILS
.Where(n => !condition.SaleType.HasValue || n.SALE_TYPE == condition.SaleType.Value)
Essentially, you want to return all rows when condition.SaleType does not have value; otherwise, you make a comparison to condition.SaleType.Value.
I am trying to write session in controller. My structure is
$_SESSION['a'][0] = 1;
$_SESSION['a'][1] = 2;
$_SESSION['a'][2] = 3;
And I am trying this
Configure::write('Session', ['a' =>'1'])
But it is not working. How do this in cakephp 3 way
To write variable in Session in CakePHP 3 you need to write following code :
$this->request->session()->write('Your Key',Your_array);
To know more information you can visit here :
http://book.cakephp.org/3.0/en/development/sessions.html
To make things perfectly clear:
// code writing array to session
$a = [ "abc" => "word", "123" => 42, "?" => $b ];
$a["more"] = "if you need to add";
$a[] = "whatever";
$this->request->session()->write( 'my_array', $a );
// code reading array from session
$recall = $this->request->session()->read( 'my_array' );
debug( sprintf( "What's the word? [%s]", $recall["abc"] ) );
You can simply use
$session->write([
'key1' => 'blue',
'key2' => 'green',
]);
I am refering to
http://book.cakephp.org/3.0/en/development/sessions.html#reading-writing-session-data
The answer is that this cannot be done in CakePHP 3.x
In vanilla PHP, it's possible to do this:
<?php
session_start();
$_SESSION['a'][0] = 1;
$_SESSION['a'][1] = 2;
$_SESSION['a'][2] = 3;
var_dump($_SESSION);
?>
Which will output:
array(1) {
["a"]=> array(3) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
}
}
This is correct, and what should happen.
In CakePHP, you cannot specify arrays in the session key. For example:
$this->request->session()->write('a[]', 1);
$this->request->session()->write('a[]', 2);
$this->request->session()->write('a[]', 3);
Will not work.
If you remove the [] the value will get overwritten. For example:
$this->request->session()->write('a', 1);
$this->request->session()->write('a', 2);
$this->request->session()->write('a', 3);
The value of $this->request->session()->read('a') would be 3. The values 1 and 2 have been overwritten. Again, this is to be expected because you're overwriting the key a each time. The equivalent vanilla PHP for this is:
$_SESSION['a'] = 1;
$_SESSION['a'] = 2;
$_SESSION['a'] = 3;
Due to the lack of an indexed array, $_SESSION['a'] gets overwritten each time. This is normal behaviour. It needs to have the indexes (e.g. ['a'][0], ['a'][1], ...) to work!
The other answers where they have given things like key1 and key2 are not appropriate. Because there are many situations where you want everything contained within an indexed array. Generating separate key names is wrong for this type of scenario.
My edit of the accepted answer was rejected, so I present the - seemingly necessary - explicit code example, for the benefit of #Andy and others.
// code to write to session
$a = [ 0 => "zero", 1 => "one", 2 => "two" ];
$a[] = "three";
$this->request->session()->write( 'my_array', $a );
// code to read from session
$z = $this->request->session()->read( 'my_array' );
debug( $a[3] ); // outputs "three"
Im getting this error when I execute the following code, any Ideas how to fix it?
LINQ to Entities does not recognize the method 'Int32 Min(Int32, Int32)' method, and this method cannot be translated into a store expression.
result = items.ToList()
.Select(b => new BatchToWorkOnModel()
{
BatchID = b.Batch.ID,
SummaryNotes = b.Batch.Notes,
RowVersion = b.Batch.RowVersion,
Items = items
.Select(i => new ItemToWorkOnModel()
{
SupplierTitle = i.Title,
ItemID = i.ID,
BatchID = i.BatchID ?? 0,
ItemDate = i.PubDate,
// KB - Issue 276 - Return the correct Outlet name for each item
Outlet = i.Items_SupplierFields != null ? i.Items_SupplierFields.SupplierMediaChannel != null ? i.Items_SupplierFields.SupplierMediaChannel.Name : null : null,
Status = ((short)ItemStatus.Complete == i.StatusID ? "Done" : "Not done"),
NumberInBatch = i.NumInBatch,
Text = string.IsNullOrEmpty(i.Body) ? "" : i.Body.Substring(0, Math.Min(i.Body.Length, 50)) + (i.Body.Length < 50 ? "" : "..."),
IsRelevant = i.IsRelevant == 1,
PreviouslyCompleted = i.PreviouslyCompleted > 0 ? true : false
}).ToList()
})
.FirstOrDefault();
It seems Math.Min is not implemented by the EF query provider. You should be able to fix it by simply applying AsEnumerable on your items collection to do the expression using Linq to Objects instead;
Items = items.AsEnumerable().Select(i => new ItemToWorkOnModel()...
If you add a where condition to the item selection (seems a little strange to take all items in the whole table), you'll want to add it before AsEnumerable() to allow EF to do the filtering in the database.
Also, you only want the first result from the query, but you're fetching all of them using ToList() before cutting the list down to a single item. You may want to remove the ToList() so that EF/the underlying database can return only a single result;
result = items.Select(b => new BatchToWorkOnModel()...
You do not need Math.Min.
The line in question is:
Text = string.IsNullOrEmpty(i.Body)
? "" : i.Body.Substring(0, Math.Min(i.Body.Length, 50)) + (i.Body.Length < 50 ? "" : "...")
So what does this line return?
If i.Body is null or empty it returns an empty string. If it is 50 or more characters long it returns a substring of 50 characters and appends "...".
If the length is less than 50 it takes a substring with the length of the string and appends an empty string. But that's just the original string.
Text = string.IsNullOrEmpty(i.Body)
? "" : (i.Body.Length < 50 ? i.Body : i.Body.Substring(0, 50) + "...")
If I do:
int updateGamePlays = db.tblArcadeGames.Where(c => c.ParentGameID == GameID).Sum(c => c.Plays);
If no records are returned in this query it throws:
System.InvalidOperationException: The null value cannot be assigned to
a member with type System.Int32 which is a non-nullable value type.
The only way to get it to return 0 is by doing:
int updateGamePlays = db.tblArcadeGames.Where(c => c.ParentGameID == GameID).Sum(c => (int?)c.Plays) ?? 0;
In the database c.Plays is a non-nullable int.
In set theory the sum of an empty set should equal 0 (ref). How comes in Linq-to-SQL did they decide to make it return null?
According to a source at Microsoft, Sum() on an empty set is null because of the way it works in SQL:
when the table is empty i´m getting this exception: InvalidOperationException
In SQL, Sum() aggregate operator returns null for an empty set. So this is as designed.
Another alternative is to add a 0 to the set to make sure there's always at least one value.
int updateGamePlays = db.tblArcadeGames.Where(c => c.ParentGameID == GameID)
.Select(c => c.Plays)
.Concat(new [] { 0 })
.Sum();
You can use the more general Aggregate method with a seed of zero:
int updateGamePlays = db.tblArcadeGames
.Where(c => c.ParentGameID == GameID)
.Aggregate(0, (a, c) => a + c.Plays);
This does not require using nullable types.