Get Raw SQL of Insert Statement - laravel

I am looking for a way to get the correct SQL queries for an INSERT statement. I'm having to export this data for use in another (non-laravel) system. The post at How to get the raw SQL for a Laravel delete/update/insert statement? got me part of the way there but my queries are still parameterized:
Post::all()->each(function($post)
{
$builder = DB::table('posts');
$insertStatement = $builder->getGrammar()->compileInsert($builder->select(['created_at', 'title']), [
'created_at' => $post->created_at,
'title' => $post->title
]);
Storage::disk('sql')->append('posts-latest.sql', $insertStatement);
dump($insertStatement);
}
this results in...
insert into `posts` (`created_at`, `title`) values (?, ?)
So I've managed to set the fields to be updated but how to swap out the parameters for real values?

You can do this:
Post::all()->each(function($post){
$builder = DB::table('posts');
$grammar = $builder->getGrammar();
$values = [
'created_at' => $post->created_at,
'title' => $post->title
];
$table = $grammar->wrapTable($builder->from);
if (!is_array(reset($values))) {
$values = [$values];
}
$columns = $grammar->columnize(array_keys(reset($values)));
$parameters = collect($values)->map(function ($record) use ($grammar) {
$record = array_map(function($rec){
$rec = str_replace("'", "''", $rec);
return "'$rec'";
},array_values($record));
return '('.implode(', ', $record).')';
})->implode(', ');
$insertStatement = "insert into $table ($columns) values $parameters";
// $insertStatement should contains everything you need for this post
});

I ended up discovering DB::pretend which will generate the query without running it. Then it's a case of substitution. It seems that there is no way to get the raw SQL without substitution due to the use of parameters.
Post::all()->each(function($post)
{
$builder = DB::table('posts');
$query = DB::pretend(function() use ($builder, $post)
{
return $builder->insert([
'created_at' => $post->created_at,
'title' => $post->title,
'content' => $post->content,
'featured_image_link' => $post->featured_image_link,
'slug' => $post->slug
]);
});
$bindings = [];
collect($query[0]['bindings'])->each(function($binding) use (&$bindings)
{
$binding = str_replace("'", "\\'", $binding);
$bindings[] = "'$binding'";
});
$insertStatement = Str::replaceArray('?', $bindings, $query[0]['query']);
Storage::disk('sql')->append('posts-latest.sql', $insertStatement.';');
});

Related

Laravel 7 : Why I am Getting Only First Array? I want to Fetch All Category ID data

I am getting a issue while fetching array data in Laravel 7 here is my code
https://i.stack.imgur.com/IZbg6.png
and the result is : https://i.stack.imgur.com/ByKaV.png
It is fetching only one array data. I don't know where i am missing.
If anybody know the error, please help me to solve this issue.
Below is my code ======================================
$cat_id = $category->id;
$location = null;
$sites = \DB::select( 'SELECT id FROM sites WHERE category_id = ?', [ $category->id ]);
$all = [ ];
foreach( $sites as $s ) {
$all[ ] = $s->id;
}
$sites = $all;
$all_cat_id = implode(',', array_map('intval', $sites));
// echo "<pre>";
// print($all_cat_id);
// die();
$sites = Sites::withCount('reviews')->orderBy('reviews_count', 'desc')->where('id', [$all_cat_id])->paginate(10);
return view('browse-category', [ 'activeNav' => 'home',
'reviews' => $reviews,
'sites' => $sites,
'category' => $category,
'all_categories' => $all_categories,
'location' => $location
]);
$sites = Sites::withCount('reviews')->orderBy('reviews_count', 'desc')->whereIn('id', [$all_cat_id])->paginate(10);
You need to use whereIn() instead of where()
whereIn() checks column against array.

Symfony : How to fetch data in a table which is not an entity

I would like to know if it's possible to use Doctrine to fetch some data in a table which is not an entity.
use Doctrine\DBAL\Driver\Connection;
$connection->fetchAll("SELECT ...");
I tried to use the Connection namespace. this one is working with my entities, but not with the table i want.
This code is actually working, but i'm using PDO to connect the database to execute the query. So the Ajax request is not fast enough. And my SQL query must be prepared to avoid security breaches.
Thanks for your help
/**
* #Route("/api/search", name="map_api_search")
*/
public function search(Connection $connection, Request $request, ObjectManager $manager): Response
{
if ($ajaxRequest = $request->getContent()) {
$requestContent = json_decode($ajaxRequest, true);
$content = $requestContent["content"];
$config = new \Doctrine\DBAL\Configuration();
$connectionParams = array(
'dbname' => 'smartport',
'user' => 'root',
'password' => '',
'host' => '127.0.0.1:3306',
'driver' => 'pdo_mysql',
);
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
// Prepare the query
$sql = "SELECT nom, lon, lat, id FROM `chimie_stations2` WHERE nom LIKE '%$content%' AND aasqa = 'PACA'";
// Execute SQL query
$stmt = $conn->query($sql);
//Prepare an array to push all the results from the query
$results = array();
// Processing...
while ($data = $stmt->fetch()) {
$results[] = $data;
}
if (($results)) {
return new JsonResponse([
'result' => true,
'results' => json_encode($results),
]);
} else {
return new JsonResponse([
'result' => false,
]);
}
}
}
If you want to prepare your SQL query :
public function myFunction(EntityManager $entityManager)
{
$connection = $entityManager->getConnection();
$sql = 'SOME SQL HERE';
$stmt = $connection->prepare($sql);
$stmt->execute();
$stmt->fetchAll();
}

Laravel isDirty method mass assignment

My code is saving data of only one field(efirst) if it's changed by the isDirty() method, and it's working correctly. How can I achieve the same result if I have ten fields without writing each field name?
Controller:
public function update(TeacherRequest $request, $id)
{
$teacher = Teacher::find($id);
$teacher->efirst = $request->efirst;
if ($teacher->isDirty()) {
$new_data = $teacher->efirst;
$old_data = $teacher->getOriginal('efirst');
if ($teacher->save()) {
$teacher->update($request->except('qual_id', 'id', 'profile_pic'));
DB::table('teacher_logs')->insert(
[
'user_id' => $user->id,
'teacher_id' => $teacher->id,
'old_value' => $old_data,
'new_value' => $new_data,
]);
}
}
}
If you don't want to write $teacher->field = $request->value; a bunch of times, you may use a loop:
foreach($request->except("_token") AS $field => $value){
$teacher->{$field} = $value;
}
if($teacher->isDirty()){
$new_data = [];
$old_data = [];
foreach($request->except("_token") AS $field => $value){
$new_data[$field] = $value;
$old_data[$field] = $teacher->getOriginal($field);
}
}
Note: You'll need to convert $new_data and $old_data to arrays so you can reference each field and value properly, and do some additional logic on the insert of your teacher_logs table to handle, but that should give you an idea.

Got error 'Trying to get property 'id' of non-object' even dd function return it right

I have to display data from post table based on user. But, I always get error
Trying to get property 'id' of non-object
even though dd($user) and dd($post) return it right. dd($user) return 1st row, dd($post)return 1st row. When commenting all the 'dd' function , I got 'Trying to get property 'id' of non-object' at $post = post::find($user->id);. However when I dd($post->article_title, $post->id),I do get the data
$RMM = DB::table('companies')->where('branch', 'RMM')->get();
foreach ($RMM as $RMM) {
$user = User::find($RMM->id);
$post = post::find($user->id);
$post_data = array('title' => $post->article_title,
'name' => $post->author,
'date' => date('Y-m-d', strtotime($post->date)),
);
result of dd(post)
result of dd(user)
Be aware, when you dd() something it die at first iteration in foreach, error may occurs in another iterates, maybe id 1 is exists in user but 3 or 4 is not.
use something like this:
$RMM_details = Company::where('branch', 'RMM')->get();
$RMM_details->transform(function($RMM)use($user){
$user = User::find($RMM->id);
$post = post::find($user->id);
return [
'title' => $post->article_title,
'name' => $post->author,
'date' => date('Y-m-d', strtotime($post->date)),
];
});
It might be because
$post = post::find($user->id);
is returning null value at some stances.
Check if it is empty or not by using the function empty and try again.
$RMM = DB::table('companies')->where('branch', 'RMM')->get();
foreach ($RMM as $RMM) {
$user = User::find($RMM->id);
if(!empty($user->id){
$post = post::find($user->id);
}
$post_data = array('title' => $post->article_title,
'name' => $post->author,
'date' => date('Y-m-d', strtotime($post->date)),
);

How to insert value of my checkbox to different column in database codeigniter

This should be like this
ID|access1|access2|access3|
and values:
1|1|0|1
//myController
$basic_data = array();
$select_access1 = $_POST("select_access1");
$select_access2 = $_POST("select_access2");
$select_access3 = $_POST("select_access3");
$select_access4 = $_POST("select_access4");
$select_access5 = $_POST("select_access5");
$basic_data[] = array('accs_trans_sec'=>$select_access1,'accs_acctng_sec'=>$select_access2, 'accs_admin_sec'=>$select_access3,'accs_dashboard_sec'=> $select_access4, 'accs_reports_sec'=>$select_access5);
$this->RoleModel->saveRole($basic_data);
//myModel
public function saveRole($basic_data)
{
foreach($basic_data as $value) {
$this->db->insert('roles_global_access', $basic_data);
}}
You can set that data to array just like this:
$data = array(
'column1' => 'My Value 1',
'column2' => 'My Value 2',
'column3' => 'My Value 3'
);
$this->db->insert("table_name", $data);
Let's assume that you are getting the values of your checkbox based on your $_POST variables.
Since you've declared $basic_data as array() no need to cast it as $basic_data[].
So on your controller it should be like this:
$basic_data = array(
'accs_trans_sec'=>$select_access1,
'accs_acctng_sec'=>$select_access2,
'accs_admin_sec'=>$select_access3,
'accs_dashboard_sec'=> $select_access4,
'accs_reports_sec'=>$select_access5
);
And your model there's no need to use loop since you are inserting Object data it should look like this:
public function saveRole($basic_data)
{
$this->db->insert('roles_global_access', $basic_data);
return ($this->db->affected_rows() != 1) ? false : true;
}
so basically, if the model returns true then it successfully inserted the data.
To check if data is inserted successfully:
$result = $this->RoleModel->saveRole($basic_data);
if($result == true){
echo ("Successfully inserted!");
}else{
echo ("Problem!");
}
First, you are not getting post data in the correct way. With $_POST have to use square brackets [].
Second, Don't use foreach loop in the model
Get data in the controller like this
$basic_data = array(
'accs_trans_sec' => $_POST['select_access1'],
'accs_acctng_sec' => $_POST['select_access2'],
'accs_admin_sec' => $_POST['select_access3'],
'accs_dashboard_sec' => $_POST['select_access4'],
'accs_reports_sec' => $_POST['select_access5']
);
$this->RoleModel->saveRole($basic_data);
Model
public function saveRole($basic_data){
return $this->db->insert('roles_global_access', $basic_data);
}
You should try this.
Controller:
$this->RoleModel->saveRole($_POST);
Model:
public function saveRole($basic_data){
extract($basic_data);
$dataset = array(
'accs_trans_sec' => $basic_data['select_access1'],
'accs_acctng_sec' => $basic_data['select_access2'],
'accs_admin_sec' => $basic_data['select_access3'],
'accs_dashboard_sec' => $basic_data['select_access4'],
'accs_reports_sec' => $basic_data['select_access5']
);
$this->db->insert('roles_global_access', $dataset);
}

Resources