How to check if data is already in database using PHP? - php

Situation:
My PHP script will run once a way.
and that will store data in my database.
Since 1 week is good enough for me, so I only want to keep just that.
Let's say if today is Friday OR 5 (in my case).
Is there a way to check if date == 5 is already exist in the database, and possibly override it with the one ?
If today is Friday/5, then all the old data with date == 5 should be overridden and store the new one instead.
Literally, I only want to store one full week worth of data.
Tomorrow, and the next will repeat the same logic.
Here is how I insert my data into my database :
$data = new Data;
$data->name = $name;
$data->description = $description;
$data->dayOfWeek = $today; // could be 0,1,2,3,4,5,6
$data->save();
I am not sure, how do I accomplish that in Laravel.
Any tip/suggestion will be much appreciated !

Why don't you do this outside of your foreach loop - before you insert
Data::where("dayOfWeek","=", $today )->delete();
That should take care of what you want, then you can continue insert just like normal:
$data = new Data;
$data->name = $name;
$data->description = $description;
$data->dayOfWeek = $today; // could be 0,1,2,3,4,5,6
$data->save();

You can use INSERT ... ON DUPLICATE KEY UPDATE eg. like that
INSERT INTO `data` (`name`, `description`, `day`) VALUES (:name, :description, :day)
ON DUPLICATE KEY UPDATE name = VALUES(name), description = VALUES(description)
Of course you have to declare unique key on day field to make it work.

If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, an UPDATE of the old row is performed. For example, if column a is declared as UNIQUE and contains the value 1, the following two statements have identical effect:
Sample Code:
INSERT INTO table (a,b,c) VALUES (4,5,6)
ON DUPLICATE KEY UPDATE c=9;

Firstly get the data from the database;
$data = Data::where('dayOfWeek', $today)->first();
Then check to see if the data is there, if it is update if not create.
if (!is_null($data)){
$data->update($new_attribute_data)
}
else {
Data::create($new_attribute_data);
}
As a note: Using the update method can require you to fill the $fillable array within your model if you putting GET or POST data into it. You can do it like so;
class Data extends Eloquent {
...
protected $fillable = ['name','description','dayOfWeek'];
}
And Laravel will fill the Model Attribute with the corresponding data within the Input.
EDIT:
As a faster way for the above method, use the updateOrCreate method;
Data::updateOrCreate(['dayOfWeek' => $today], $new_attribute_data);
This will search for Data models with attributes that match the first parameters, and will update its other attributes with the second parameter. Ref

Related

Why Laravel updateOrCreate() & upsert() both need argument to uniquely identify records?

Both updateOrCreate() & upsert() do the same thing, insert or update, I think they both generate SQL INSERT INTO ON DUPLICATE KEY. So I feel providing argument to uniquely identify records seems unnecessary.
Why do they need "the second argument lists the column(s) that uniquely identify records within the associated table." ?
The reason I can think of maybe in some case they do not generate the sql INSERT INTO ON DUPLICATE KEY so they may need arguments to uniquely identify records? But is this the case ?
The updateOrCreate method find a one record matching the constraints passed as the first parameter and If a the record is found it will update the match with the attributes passed as the second parameter
If no matching record is found a it will be create record with both the constraints passed as the first parameter and the attributes passed as the second parameter.
I check Laravel source and it confirms my doubt, for upsert(), refer to https://github.com/illuminate/database/blob/master/Query/Grammars/MySqlGrammar.php#L164
It generates sql insert on duplicate key update but the $uniqueBy argument is not used at all! (It shouldn't)
public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update)
{
$sql = $this->compileInsert($query, $values).' on duplicate key update ';
$columns = collect($update)->map(function ($value, $key) {
return is_numeric($key)
? $this->wrap($value).' = values('.$this->wrap($value).')'
: $this->wrap($key).' = '.$this->parameter($value);
})->implode(', ');
return $sql.$columns;
}
For updateOrCreate() it actually does NOT generate insert on duplicate key update but TWO sql clauses!!
https://github.com/illuminate/database/blob/master/Eloquent/Builder.php#L469
public function updateOrCreate(array $attributes, array $values = [])
{
return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
$instance->fill($values)->save();
});
}
It is not easy to see the generated sql clause here but checking log, it is 2 clauses, one insert into and one update

Update data into table from dynamically created input field

I have 2 models Tour.php
public function Itinerary()
{
return $this->hasMany('App\Itinerary', 'tour_id');
}
and
Itinerary.php
public function tour()
{
return $this->belongsTo('App\Tour', 'tour_id');
}
tours table:
id|title|content
itineraries table:
id|tour_id|day|itinerary
I have used vue js to create or add and remove input field for day and plan dynamically. And used the following code in tour.store method to insert into itineraries table:
$count = count($request->input('day'));
$temp_day = $request->input('day');
$temp_itinerary = $request->input('itinerary');
for($i = 0; $i < $count; ++$i)
{
$itinerary = new Itinerary;
$itinerary->tour_id = $tour->id;
$itinerary->plan = $temp_itinerary[$i];
$itinerary->day = $temp_day[$i];
$itinerary->save();
}
And was successful in inserting the records.And applied same code in tour.store method. Instead of updating the rows, it inserted new rows to the table. What would be the best solution for this ?
For updation try this code
$itinerary = Itinerary::find($tour_id);
$itinerary->plan = $temp_itinerary[$i];
$itinerary->day = $temp_day[$i];
$itinerary->save();
The way you are using is to insert/create new records. To update you can use.
Itinerary::find($tour_id)->update(
['column_name'=> value]
);
Where find method takes a primary key of the table.
This will update your existing record. You can update as many columns as you want just pass in array update takes. You can also use save method as mentioned in other answer.
Check Laravel Update Eloquent
EDIT
$iterneary = Itenerary::where('tour_id', $tour_id)->first();
Now you can update this iterneary object to whatever you want.
this is how i did it. First saved all the tours in $tours[] array.
foreach($tours as $tour) {
$itinerary->tour()->updateOrCreate(['id'=> $tour['id']],$tour);
}
updateOrCreate because you may need to add new tours while updating. I know this doesnt answer your issue exactly but this could atleast give you an idea.

MySQL query with temporary column's name in Yii

I want to select only year from records ane make from this data assoc array
$wynik = $model_post::model() -> findAllBySql('SELECT DISTINCT YEAR(create_time) as rok FROM tbl_post');
for($i;$i<count($wynik);$i++)
{
$rok[$wynik[$i]->rok]=$wynik[$i]->rok;
}
but I got the exception
_Property "Post.rok" is not defined._
How can I make it correct?
If I remember correctly this should work in Yii1 as well: define a variable public $rok; in your model_post class, and it will automatically be populated when you use that query.

Codeigniter how to map a class sent to a model

I have a SectorModel with this function:
public function update(Sector $sector) {
$this->db->where('sector_id', $sector->getScetor_id());
return $this->db->update(_SECTOR_, $sector);
}
There are times that I’ll change only the name of the Sector object:
$Sector = new Sector();
$Sector->setSector_name = 'test';
$this->SectorModel->update($Sector);
The generated select looks like:
UPDATE realestate_sector SET sector_name = 'teste', sector_description = NULL
It will update but will set all other properties to NULL because it was not set on my object.
Right now, I have to fill the whole object before sending it.
Is there a way to map the Sector class and update only what was sent on the object?
Thanks in advance for any help.
Sorry for any typos, my English is not good =)
Just loop through all your object's properites and then if any is NULL just drop it with unset.
Here is your model's method edited to achieve that:
public function update(Sector $sector)
{
foreach($sector as $k=>$v)
{
if($v === NULL)
unset($sector->$k)
}
$this->db->where('sector_id', $sector->getScetor_id());
return $this->db->update(_SECTOR_, $sector);
}
Here you can find some info about iterating objects in PHP
The easiest to do this would be to rather use a array - docs here http://codeigniter.com/user_guide/database/active_record.html#update - you just create a array of all the columns with their values that you want to update and perform a $this->db->update('mytable', array('name' => 'test'), array('id' => $id)); call. This will only update the columns you specified in the First array. With the second array acting as your WHERE expression.
The only reason I can think of as to why your other values are being set to NULL is because in your example you create a new instance of the class and the other values must either have been set to nothing or are set to NULL. It would (If this is the case) be better to get a record from the table and then change and values on the populated record and pass that to the function to update.
Hope that helps.

How to code in OO PHP?

How can I do this in OO PHP:
A form ('in newstudent.php') asks the user to enter his name, course and year.
After selecting 'Submit' button, the page will go to 'records.php'
records.php - contains a table that displays all the records (columns: name, course, year)
when the user selects 'Submit', the new record will be added to the database which has a table named STUDENTS
SQL code
CREATE TABLE STUDENTS(
NAME VARCHAR(25) NOT NULL,
COURSE VARCHAR(25) NOT NULL,
YEAR INT NOT NULL,
CONSTRAINT STUDENTS_PK PRIMARY KEY(NAME));
*please don't mind about the primary key coz i know it's not accurate to use name as the primary key. this is just for exmple purposes.
and also...How can i manipulate data in DB using OO PHP?
Thanks
Read a book
Search Google
Create Student Object
Create Database Object
Query Database Object to insert Student Object
Well, if you want to switch to a OO method of representing students in a database, how about a 'Student' class that looks something like the definition below (although this is very basic, and not a full ORM in any way). It takes you halfway to an ActiveRecord style approach.
Note that I have assumed you will use an integer id column, not doing so makes the whole class annoying.
class Student {
var $id = -1;
var $name;
var $course;
var $year;
public static function newFromID ($id)
{
//fetch a row ($row) from the students table matching the given id
//perhaps returning false if the student doesn't exist?
return self::newFromRow($row);
}
// this method should return a new student object given a specific db row
// and should be called from newFromID. This function means that if the table
// changes, modifications only have to be made in one place
public static function newFromRow($row)
{
$obj = new Student();
//fill in the fields of the object based on the content of the row
return $obj;
}
public static function getAllStudents()
{
//perhaps return an array of student objects, by doing a broad select,
//and passing each row to newFromRow?
}
//this should save the object to the database, either inserting or updating as appropriate
public function save()
{
if($this->id == -1)
{
//insert, store the auto_increment id in $this->id
} else {
//update
}
}
}
So, to create a new student, and save it to the database:
$student = new Student();
$student->name = "John Smith";
$student->course = "French";
$student->year = 2;
$student->save();
In reality, it is often more sensible to use an existing ORM system, but if that isn't an option, you can consider writing your own.
Maybe you talk about ORM - Object Relation Mapping patterns? There are many different approaches to get mapped SQL data objects to PHP classes: Propel, Doctrine (both can be used with Symfony framework), ActiveRecord.
Of course, you can try to implement your own ORM system. You need to write data access layer for this ORM, classes which describes SQL tables and many other things. It is very interesting (for educational purposes).

Categories