When will the database connection be closed in prestashop 1.6.1.3 version? - mysql

When will the database connection be closed in prestashop 1.6.1.3 after a db instance is created by $db = Db::getInstance();
Do I need to close the database connection manually by writing any code db close function?
Or the db class in prestashop will handle this?
Actually when will be the PrestaShop db connection will be closed after a db object is created by $db = Db::getInstance();?
See below code which is a simple php file in my root directory of prestashop to update one of my tables and this page is called every one minute by cron job task ,here I am not closing the connection anywhere ,do we need to close it ?
$CheckStatusSql = "select * from ticket_status where item_id='$ItemID' and ticket_series='$TicketSeries' and status='BOOKED' ";
$db = Db::getInstance();
$result = $db->executeS($CheckStatusSql, false);
$ChangeStatus ='';
while ($row = $db->nextRow($result)) {
$status = $row['status'];
$booked_on = $row['booked_on'];
$ticket_no = $row['ticket_no'];
$to_time = strtotime(date("Y-m-d H:i:s"));// Time Now
$from_time = strtotime($booked_on); //Booked Time
$time_diff_minutes=round(abs($to_time - $from_time) / 60,2);
if($time_diff_minutes>$checkMinutes){
$ChangeStatus=$ChangeStatus."Booked ticket no: '".$ticket_no."' exceeds 30 Minutes and its now about ".$time_diff_minutes." minutes, status changed to AVAILABLE<br><br\>";
$updateSql = "UPDATE ticket_status SET status = 'AVAILABLE', booked_on = NULL WHERE item_id='$ItemID' and ticket_series='$TicketSeries' and status='BOOKED' and ticket_no='$ticket_no'";
$bookResult = $db->executeS($updateSql, false);
}
}
That is I am just including the config file (require 'config/config.inc.php';) and creating a db object and then executing my query as shown below :
require 'config/config.inc.php';
$checkMinutes = 30;// In minutes
$checkTimeInSeconds = $checkMinutes*60;
$sql = 'SELECT * FROM ps_ticket WHERE status=5';
$db = Db::getInstance();
$result = $db->executeS($sql, false);
$i=1;
while ($row = $db->nextRow($result)) {
$time = strtotime($row['hold_on']);
$curtime = time();
if(($curtime-$time) > $checkTimeInSeconds) { ///3600 seconds
$sql = 'UPDATE `'._DB_PREFIX_.'lopp_ticket`
SET
`id_customer` = 0,
`hold_on`=0,
`status` = 1
WHERE `ticket_id` = '.$row['ticket_id'];
if(Db::getInstance()->execute($sql)) {
echo $row['ticket_id'].' Updated'.'<br>';
}
}
else {
echo $row['ticket_no'].'No'.'<br>';
}
$i++;
}
So here do I need to close the db connection anywhere in the above code or PrestaShop will handle itself?
Because the server admin is saying too many database sessions are been opened by our code ,
Also Is there anyway to check from where too many db sessions are open/active always ?

As far as i know i never have closed a DB connection in Prestashop.
There documentation also does not explicitly state to close each DB request.
Looking into there source code they also never run a close command after a DB connection.
Looking into the classes\db\DbMySQLi.php class we can find the function below.
/**
* Destroys the database connection link.
*
* #see DbCore::disconnect()
*/
public function disconnect()
{
#$this->link->close();
}
Then we will look into classes\db\Db.php where we find that the function $this->disconnect() is called. So its safe to say they will close all there DB connections automatically.
/**
* Closes connection to database.
*/
public function __destruct()
{
if ($this->link) {
$this->disconnect();
}
}

Related

How do I reset a MySQL column in a table every year?

I have a column named lv_casual in a table called tbl_employees. I need to reset the column to 0 at a specific date every year.
You can use MySQL event schedule. Providing an example below.
You have to enable the schedular first
SET GLOBAL event_scheduler = ON;
Then create the event
CREATE EVENT your_event_name
ON SCHEDULE EVERY 1 YEAR
STARTS '2021-10-12 00:00:00'
DO
UPDATE table SET column=0;
Check MySQL document for creating event
You can use a cron job to run once per year at end of the year, create a script that will reset all the records on that column to 0.
/usr/local/bin/ea-php99 /home2/accounname/https://example.com/cron_execute_file
okay bro this how your execute file should look like cron_execute_file.php
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection to db
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "UPDATE employees SET leaves='12' WHERE leaves >= 0";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . $conn->error;
}
$conn->close();
?>
N/B: [#Shaido][1] and any dauche bag thinking of, Please stop editing my answers, just give your own answers, adding fullstops and grammar to my answers to gain budges is a lame thing note this is not a English grammar class. Stay away from my answers, give your own answers. Polite Notice failure to I'll send some visitors to you machines.
[1]: https://stackoverflow.com/users/7579547/shaido

SyncFramework Provisioning Exception

I am getting a DbPartialllyProvisionedException when i try provisioning the microsoft azure scope. It is returning an error "Invalid column name 'ISQLHELPERCACHEDPRIMARYCLIENTNAME'." And I am not sure why, since it was working previously. A few changes were made to the ce database, ie more tables were added, but that was it. If anyone could help it would be much appreciated.
Code for the provisioning:
*
SqlCeConnection sqlCEConnProv = new SqlCeConnection(SQLCEConnectionString);
sqlCEConnProv.Open();
SqlCeCommand cmd = sqlCEConnProv.CreateCommand();
cmd.CommandText = "select table_name from information_schema.tables where TABLE_TYPE <> 'VIEW' AND TABLE_NAME NOT LIKE '__sys%'";
SqlCeDataReader reader = cmd.ExecuteReader();
List<string> tableNames = new System.Collections.Generic.List<string>();
while (reader.Read())
{
tableNames.Add(reader.GetString(0));
}
SqlConnection sqlAzureConnProv = new SqlConnection(SQLAzureConnectionString);
DbSyncScopeDescription myScope = new DbSyncScopeDescription(scopeName);
foreach (string tableName in tableNames)
{
DbSyncTableDescription Customer = SqlCeSyncDescriptionBuilder.GetDescriptionForTable(tableName, sqlCEConnProv);
myScope.Tables.Add(Customer);
}
// Setup SQL Server for sync
SqlCeSyncScopeProvisioning sqlServerProv = new SqlCeSyncScopeProvisioning(sqlCEConnProv, myScope);
sqlServerProv.ObjectPrefix = syncPrefix;
if (!sqlServerProv.ScopeExists(scopeName))
// Apply the scope provisioning.
sqlServerProv.Apply();
// Setup SQL Database for sync
SqlSyncScopeProvisioning sqlAzureProv = new SqlSyncScopeProvisioning(sqlAzureConnProv, myScope);
sqlAzureProv.ObjectPrefix = syncPrefix;
if (!sqlAzureProv.ScopeExists(scopeName))
{
// Apply the scope provisioning.
//string script = sqlAzureProv.Script(); // debugging
sqlAzureProv.Apply();
}
sqlCEConnProv.Close();
sqlAzureConnProv.Close();
*

Too many sql connections error : due to long polling

I have designed a coding platform just like Spoj and Codeforces for competitions to be organised in my college on LAN.
I have used long polling there so that any announcements from the Admin can be broadcasted to all users with a JavaScript alert message. When anything is posted on the forum then the admin also gets a notification.
But for just 16 users (including the 1 Admin) accessing the site, the server went down showing too many sql connections. I restarted my laptop (server) and it continued for a while, then again went down; giving the same error message as before.
When I removed both long-poll processes everything continued smoothly.
Server-side code for long-poll:
include 'dbconnect.php';
$old_ann_id = $_GET['old_ann_id'];
$resultann = mysqli_query($con,"SELECT cmntid FROM announcements ORDER BY cmntid DESC LIMIT 1");
while($rowann = mysqli_fetch_array($resultann)){
$last_ann_id = $rowann['cmntid'];
}
while($last_ann_id <= $old_ann_id){
usleep(10000000);
clearstatcache();
$resultann = mysqli_query($con,"SELECT cmntid FROM announcements ORDER BY cmntid DESC LIMIT 1");
while($rowann = mysqli_fetch_array($resultann)){
$last_ann_id = $rowann['cmntid'];
}
}
$response = array();
$response['msg'] = 'new';
$response['old_ann_id'] = $last_ann_id;
$resultann = mysqli_query($con, "Select announcements from announcements where cmntid = $last_ann_id");
while($rowann = mysqli_fetch_array($resultann)){
$response['announcement'] = $rowann['announcements'];
}
echo json_encode($response);
Max connections is defined. Think the default is 100 or 151 connections depending on the version of MySQL. You can see the value in "Server variables and settings" in phpmyadmin (or directly by executing *show variables like "max_connections";* ).
If that is set to something very low (say 10) and you have (say) 15 users you will hit the limit rapidly. You are giving each long polling script its own connection, and that connection is probably sitting open until that long polling script ends. You could likely reduce this by having the script disconnect after each time it checks the database, then reconnect the next time it checks (ie, if your long polling script checks the db every 5 seconds you probably have well over 4.5 seconds of that 5 seconds currently where there is a connection to the db but where the connection is not being used)
However you could have a larger number of connections, but if you trigger the ajax polling multiple times per user, each could have several simultaneous connections. This is probably quite easy to do with a minor bug in your javascript.
Possibly worse if you are using a persistent connections you might leave connections open after the user has left the page that calls the long polling script.
EDIT - update based on your script.
Note I am not sure exactly what your dbconnect.php include is doing. I might be possible to easily call a connect / disconnect function in that include, but I have just put it in this example code as using the mysqlu_close and mysqli_connect functions.
<?php
include 'dbconnect.php';
$old_ann_id = $_GET['old_ann_id'];
$resultann = mysqli_query($con,"SELECT MAX(cmntid) FROM announcements");
if($rowann = mysqli_fetch_array($resultann))
{
$last_ann_id = $rowann['cmntid'];
}
$timeout = 0;
while($last_ann_id <=$old_ann_id and $timeout < 6)
{
$timeout++;
mysqli_close($con);
usleep(10000000);
clearstatcache();
$con = mysqli_connect("myhost","myuser","mypassw","mybd");
$resultann = mysqli_query($con,"SELECT MAX(cmntid) FROM announcements");
if($rowann = mysqli_fetch_array($resultann))
{
$last_ann_id = $rowann['cmntid'];
}
}
if ($last_ann_id >$old_ann_id)
{
$response = array();
$response['msg'] = 'new';
$response['old_ann_id'] = $last_ann_id;
$resultann=mysqli_query($con,"SELECT cmntid, announcements FROM announcements WHERE cmntid>$old_ann_id ORDER BY cmntid");
while($rowann = mysqli_fetch_array($resultann))
{
$response['announcement'][]=$rowann['announcements'];
$response['old_ann_id'] = $rowann['cmntid'];
}
mysqli_close($con);
echo json_encode($response);
}
else
{
echo "No annoucements - resubmit";
}
?>
I have added a count to the main loop. But it will drop out of the loop whether anything is found once it has executed 6 times. This way even if someone leaves the page the script will only be running for a short time afterwards (max a minute). You will have to amend you javascript to catch this and resubmit the ajax call.
Also I have changed the announcement in the response to be an array. This way if there are several announcements while the script is running all will be brought back.

Mysql Server has gone away error on PHP script

I've wrote a script to batch process domains and retrieve data on each one. For each domain retrieved, it connects to a remote page via curl and retrieves the data required for 30 domains at a time.
This page typical takes between 2 - 3 mins to load and return the curl result, at this point, the details are parsed and placed into an array (page rank tools function).
Upon running this script via CRON, I keep getting the error 'MySQL server has gone away'.
Can anyone tell me if I'm missing something obvious that could be causing this?
// script dies after 4 mins in time for next cron to start
set_time_limit(240);
include('../include_prehead.php');
$sql = "SELECT id, url FROM domains WHERE (provider_id = 9 OR provider_id = 10) AND google_page_rank IS NULL LIMIT 30";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
do {
$url_list[$row['id']] = $row['url'];
} while ($row = mysql_fetch_assoc($result));
// curl domain information page - typically takes about 3 minutes
$pr = page_rank_tools($url_list);
foreach ($pr AS $p) {
// each domain
if (isset($p['google_page_rank']) && isset($p['alexa_rank']) && isset($p['links_in_yahoo']) && isset($p['links_in_google'])) {
$sql = "UPDATE domains SET google_page_rank = '".$p['google_page_rank']."' , alexa_rank = '".$p['alexa_rank']."' , links_in_yahoo = '".$p['links_in_yahoo']."' , links_in_google = '".$p['links_in_google']."' WHERE id = '".$p['id']."'";
mysql_query($sql) or die(mysql_error());
}
}
Thanks
CJ
This happens because MySQL connection has its own timeout and while you are parsing your pages, well, it ends. You can try to increase this timeout with
ini_set('mysql.connect_timeout', 300);
ini_set('default_socket_timeout', 300);
(as mentioned in MySQL server has gone away - in exactly 60 seconds)
Or just call mysql_connect() again.
Because the curl take too long time, you can consider to connect again your database before entering the LOOP for update
There are many reasons why this error occurs. See a list here, it may be something you can fix quite easily
MySQL Server has gone away

PHP + MySQL profiler

You know how vBulletin has a sql profiler when in debug mode? How would I go about building one for my own web application? It's built in procedural PHP.
Thanks.
http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html
The above link links how you can get al the sql profile information after any query.
Best way to implement it is to create a database class and have it have a "profile" flag to turn on logging of queries and the appropriate information as shown int he link above.
Example:
Class dbthing{
var $profile = false;
function __construct($profile = false){
if($profile){
$this->query('set profiling=1');
$this->profile = true;
}
...
}
function query($sql, $profile_this == false){
...
if($this->profile && !$profile_this)
$this->query("select sum(duration) as qtime from information_schema.profiling where query_id=1", true);
... // store the timing here
}
}
I use a database connection wrapper that I can place a profiling wrapper arround. This way I can discard the wrapper, or change it, without changing my base connector class.
class dbcon {
function query( $q ) {}
}
class profiled_dbcon()
{
private $dbcon;
private $thresh;
function __construct( dbcon $d, $thresh=false )
{
$this->dbcon = $d;
$this->thresh = $thresh;
}
function queury( $q )
{
$begin = microtime( true );
$result = this->dbcon->query();
$end = microtime( true );
if( $this->thresh && ($end - $begin) >= $this->thresh ) error_log( ... );
return $result;
}
}
For profiling with a 10 second threshold:
$dbc = new profiled_dbcon( new dbcon(), 10 );
I have it use error_log() what the times were. I would not log query performance back to the database server, that affects the database server performance. You'd rather have your web-heads absorb that impact.
Though late, Open PHP MyProfiler would help you achieve this, and you can extract functional sections from the code for your usage.