How to load an sql dump using symfony - php

I'm trying to make a user friendly way of testing via lime in symfony 1. I want to load a specific sql dump for each test I write (if required). The problem I face is that I don't know how to make dump loading independent of database type. Currently I'm using the shell exec() command. Here is the code :
public function loadSql()
{
$this->diag("Loading dump...");
if ($this->_sql_is_set)
{
if (file_exists($this->_getSqlPath()))
{
$this->_emptyDataBase();
$options = $this->_connection_manager->connection()->getOptions();
$dsn_parts = $this->_connection_manager->parsePdoDsn($options['dsn']);
exec("mysql -u{$options['username']} -p{$options['password']} {$dsn_parts['dbname']} < {$this->_getSqlPath()}");
return $this;
}
else
{
$this->error("Nothing to load : sql file was not found in ".$this->_getDataDir());
exit;
}
}
else
{
$this->error("Nothing to load : sql dump was not set");
exit;
}
}
$this->_connection_manager is an instance of Doctrine_Manager. Any help will with that?

Try with something like that:
public function loadSqlFiles(sfEvent $event)
{
$task = $event->getSubject();
$taskName = $task->getName();
if ($taskName == 'insert-sql') {
$conn = Doctrine_Manager::connection();
$filesPath = sfConfig::get('sf_data_dir') . '/sql/full-data';
// get all files
$files = sfFinder::type('file')->sort_by_name()->name('*.sql')->in($filesPath);
foreach ($files as $file) {
$task->logSection('custom-sql', sprintf('Inserting custom sql file (%s)', $file));
$res = $conn->getDbh()->exec(file_get_contents($file));
}
}
}

Related

Can't caching object in codeigniter

I have this following code in the Address controller
public function index()
{
if($this->session->userdata('isLogin')) {
$this->load->driver('cache');
$this->load->model('MemberModel');
if(!$this->cache->get('province') == false) {
$this->load->model('ShippingModel');
$data['provinces'] = $this->ShippingModel->the_provinces(); // it will return json object
$this->cache->save('province', $data['provinces'], 300);
} else {
$data['provinces'] = $this->cache->get('province');
}
$userdata = $this->MemberModel->getProfile($this->session->userdata('userid'));
$data['user'] = $userdata;
$this->display_member_area('member/address', $data);
}
else {
redirect(base_url());
}
}
When I want to get the data using:
var_dump($this->cache->get('province'));
the result I get always shows
bool(false)
but when I tried to do this instead
var_dump($data['provinces']) // it's show me json object, that I want
Can anyone please show me where I'am doing wrong?
Thanks in advance
Remove false from the if condition and use this code.
if(!$this->cache->get('province')) {
$this->load->model('ShippingModel');
$data['provinces'] = $this->ShippingModel->the_provinces();
$this->cache->save('province', $data['provinces'], 300);
} else {
$data['provinces'] = $this->cache->get('province');
}
Make sure you have the correct credential on your config at:
https://github.com/bcit-ci/CodeIgniter/blob/develop/application/config/memcached.php
it will be at you application/config/memcached.php file. Hostname is the ip you setup your memcached instance. You could provide multiple server if you wish.
reference on installing memcached

Subscribing and reading data from redis channels using php-redis simultaneously

I have to subscribe to all the channels of my Redis db and simultaneously read data from another hash in the same db node. The following is the code I have written for this using phpredis:
$notif = new Worker;
try {
// connect redis
$notif->connectRedisServer();
// start the worker processing
$notif->startWorkerProcess();
}
catch(Exception $e) {
exit('Exception: '.$e->getMessage());
}
class Worker {
private $redis;
public $recentHash = 'tracker.data.recent';
public $notifHash = 'tracker.settings.data';
public $serverConnectionDetails = { //Redis server connection details
};
private $redis;
// redis database used for getting recent record of every imei
const RECENTDATA_DB = 1;
public function connectRedisServer() {
if(!empty($this->redis))
return $this->redis; // already connected
$this->redis = new Redis();
if(!$this->redis->pconnect(
$this->serverConnectionDetails['redis']['host'],
$this->serverConnectionDetails['redis']['port']
))
return 'Redis connection failed.';
if(isset($this->serverConnectionDetails['redis']['password'])
&&
!$this->redis->auth($this->serverConnectionDetails['redis']['password'])
)
return 'Redis authentication failed.';
return $this->redis;
}
public function startWorkerProcess() {
$this->redis->select(self::RECENTDATA_DB);
$this->redis->pSubscribe(array('*'), array($this, 'processRedisData'));
}
public function processRedisData($redis, $pattern, $chan, $msg) {
$message = rtrim((string) $msg,",");
$tData = json_decode($message, true);
$tId = (int) $tData['tID'];
echo "Recent Published Data:";
var_dump($tData);
$data = $this->getNotifSettings($tId);
if(!empty($data)) {
echo "Redis Settings: ";
var_dump($trackerSettings);
}
}
public function getNotifSettings($tId) {
$data = $this->redis->hGet($this->notifHash, $tId); //This command doesn't return any data even if it exists for the $tId
if($data === false)
return null;
$data = json_decode($data, true);
return $data; // Always comes up as null
}
}
The problem here is that once I get subscribed to all the channels on db1 in Redis. I don't get any result if I try to run HGET, even though the data for the given key exists in the db. I have put additional comments in the code above to explain where the problem is. Check getNotifSettings() function.
Any help will be appreciated.

Php Memcached delete not working

I am using PHP Memcached & when I delete a key, I can still retrieve the key. What could I be doing wrong?
function __construct() {
$this->_cache = array();
// if we have memcache support, load it from CACHE_POOL
//
if (class_exists('Memcached')) {
$this->_mc = new Memcached('CACHE_POOL');
$servers = $this->_mc->getServerList();
if (empty($servers)) {
//This code block will only execute if we are setting up a new EG(persistent_list) entry
$this->_mc->setOption(Memcached::OPT_RECV_TIMEOUT, 1000);
$this->_mc->setOption(Memcached::OPT_SEND_TIMEOUT, 3000);
$this->_mc->setOption(Memcached::OPT_TCP_NODELAY, true);
$this->_mc->setOption(Memcached::OPT_PREFIX_KEY, "md_");
$this->_mc->addServers(self::$_MEMCACHE_IPS);
}
$current_cache = $this->_mc->get(self::CACHE_KEY);
if ($current_cache) {
$this->_cache = array_merge($this->_cache, $current_cache);
}
}
}
function delete($key) {
self::instance()->_mc->delete($key);
}
function getSafe($key) {
return isset($this->_cache[$key]) ? $this->_cache[$key] : FALSE;
}
self::instance()->delete("test");
echo(self::instance()->getSafe("test"));
After running this, the get still returns a value. Not sure what is going on here.
You should also delete cache from _cache property in terms of the retrieving method:
function delete($key) {
self::instance()->_mc->delete($key);
unset(self::instance()->_cache[$key]);
}
But do not apply this code design in your production environment.

I'm trying to save data in memcached from a php script so that my website can directly use the data

The script works fine and is setting the data, but the website code is unable to use it and is instead setting its own memcached values. My website code is written in codeIgniter framework. I don't know why this is happening.
My script code :-
function getFromMemcached($string) {
$memcached_library = new Memcached();
$memcached_library->addServer('localhost', 11211);
$result = $memcached_library->get(md5($string));
return $result;
}
function setInMemcached($string,$result,$TTL = 1800) {
$memcached_library = new Memcached();
$memcached_library->addServer('localhost', 11211);
$memcached_library->set(md5($string),$result, $TTL);
}
/*---------- Function stores complete product page as one function call cache -----------------*/
function getCachedCompleteProduct($productId,$brand)
{
$result = array();
$result = getFromMemcached($productId." product page");
if(true==empty($result))
{
//------- REST CODE storing data in $result------
setInMemcached($productId." product page",$result,1800);
}
return $result;
}
Website Code :-
private function getFromMemcached($string) {
$result = $this->memcached_library->get(md5($string));
return $result;
}
private function setInMemcached($string,$result,$TTL = 1800) {
$this->memcached_library->add(md5($string),$result, $TTL);
}
/*---------- Function stores complete product page as one function call cache -----------------*/
public function getCachedCompleteProduct($productId,$brand)
{
$result = array();
$result = $this->getFromMemcached($productId." product page");
if(true==empty($result))
{
// ----------- Rest Code storing data in $result
$this->setInMemcached($productId." product page",$result,1800);
}
return $result;
}
This is saving data in memcached. I checked by printing inside the if condition and checking the final result
Based on the CodeIgniter docs, you can make use of:
class YourController extends CI_Controller() {
function __construct() {
$this->load->driver('cache');
}
private function getFromMemcached($key) {
$result = $this->cache->memcached->get(md5($key));
return $result;
}
private function setInMemcached($key, $value, $TTL = 1800) {
$this->cache->memcached->save(md5($key), $value, $TTL);
}
public function getCachedCompleteProduct($productId,$brand) {
$result = array();
$result = $this->getFromMemcached($productId." product page");
if( empty($result) ) {
// ----------- Rest Code storing data in $result
$this->setInMemcached($productId." product page",$result,1800);
}
return $result;
}
}
Personally try to avoid 3rd party libraries if it already exists in the core framework. And I have tested this, it's working superbly, so that should fix this for you :)
Just remember to follow the instructions at http://ellislab.com/codeigniter/user-guide/libraries/caching.html#memcached to set the config as needed for the memcache server

Duplicate entries in MySQL after performing a check (PHP)

Lately, I have been getting some strange duplicate entries in my MySQL database. Entries in this table are inserted during a PUT request to a PHP page. The table contains 3 fields with no external references:
manga_id (primary key; auto increment) - bigint(20);
name - varchar(255);
manga_cid - varchar(255).
The PHP code is the following:
class MangaHandler {
private function getMangaFromName($name) {
$id = $this->generateId($name);
$mangas = new Query("SELECT * FROM tbl_manga WHERE manga_cid = '" . $this->conn->escapeString($id) . "'", $this->conn);
if(!$mangas || $mangas->hasError()) {
logError("getMangaFromName($name): " . $this->conn->getError());
return null;
}
if($mangas->moveNext()) {
return $mangas->getRow();
}
return null;
}
private function addManga($name) {
$manga_row = null;
$error = false;
$cid = $this->generateId($name);
$sql = sprintf("INSERT INTO tbl_manga(name, manga_cid) VALUES ('%s', '%s')", $this->conn->escapeString($name), $this->conn->escapeString($cid));
if(!$this->conn->execute($sql))
$error = true;
// some more code ...
if($error) {
logError("addManga($name): " . $this->conn->getError());
}
return $manga_row;
}
public function addMangaSourceAndFollow($name, $url, $source_id, $user_id, $stick_source = false, $stick_lang = 'English') {
// validate url
$manga = $this->getMangaFromUrl($url, $source_id);
if(!$manga) {
$manga = $this->getMangaFromName($name);
if(!$manga) $manga = $this->addManga($name);
// ...
}
// ...
return true;
}
}
class MangaRestService extends CommonRestService
{
public function performPut($url, $arguments, $accept, $raw) {
header('Content-type: application/json');
header("Cache-Control: no-cache, must-revalidate");
$json = json_decode($raw, true);
// some input validation and auth
$ms = new MangaHandler();
try {
$ret = $ms->addMangaSourceAndFollow(null, $json['url'], $source['source_id'], $user['user_id'], $enforce == 1);
// throw exception if some ret is invalid
// return proper json response
} catch(Exception $e) {
$conn->rollback();
logError("MangaRestService.performPut($url, [" . implode("; ", $arguments) . "], $accept, $raw): " . $e->getMessage());
echo RestResponse::getSomeErrorResponse()->toJSON();
}
}
}
$serv = new MangaRestService();
// performs some checks and invokes the appropriate GET, POST, PUT or DELETE method
// in this case it's the performPut method above
$serv->handleRawRequest();
The manga name gets filtered (only alphanumeric chars, underscore and some more characters are allowed) and becomes the manga_cid (which should be unique in the table).
The code basically checks if a manga with a specific manga_cid exists. Only if it doesn't, a new entry is inserted. I have tested the code and it works, however, after deploying the app., I have been getting entries with duplicate manga_cid (sometimes more than 2). This is a rare occurrence, as most entries remain unique. Also, I have no errors in my logs.
Could it be that for some reason, multiple HTTP PUT requests are being executed concurrently and, since there is no synchronization, INSERT gets called multiple times?
I find it very unlikely, specially because the app only lets you press the button that performs this request once before it disappears.
I have tried using MySQL transactions but it didn't solve the problem. I know that setting the field as unique will probably allow me to avoid these duplicate entries, however I would have to perform some heavy maintenance on the database in order to remove the duplicate entries first. Although this table has a simple structure, the manga_id is referenced in several other tables.
Also, I am curious as to why this is happening :-)
Just in case, here's the Query class:
class Query extends QueryBase
{
function Query($query, &$conn)
{
$this->recordset = array();
$this->has_error=0;
$regs = mysqli_query($conn->getConnection(), $query);
if(!$regs)
{
$this->has_error=1;
return;
}
$index = 0;
$this->current_index=-1;
while(($row = mysqli_fetch_array($regs, MYSQL_ASSOC)))
{
$this->recordset[$index]=$row;
$index++;
}
mysqli_free_result($regs);
}
public function moveNext()
{
if($this->current_index<(sizeof($this->recordset)-1))
{
$this->current_index++;
return 1;
}
else
return 0;
}
public function moveBack()
{
if($this->current_index>=1)
{
$this->current_index--;
return 1;
}
else
return 0;
}
public function recordCount()
{
return sizeof($this->recordset);
}
public function get($field)
{
return $this->recordset[$this->current_index][$field];
}
public function getRow()
{
return $this->recordset[$this->current_index];
}
public function hasError()
{
return $this->has_error;
}
}
Thank you for your help.
It sounds as though you are executing that block of code more than once, can you post the rest of the code? The code that deals with the 'put'?
As a general rule, if the process for checking for the existence of a value and insertion of a value are separate, there can be double entries due to someone accidentally clicking the submit button more than once (for example - or other action? image click...)
It's often a good practice to embed a duplicate submission check so that double submissions are avoided.
I'm not sure if this will fix it for you, but it would be better to return "false;" instead of returning "null" upon failure from your getManageFromName() method.
Another thing to check would your hasErrors() method; it might be returning errors for some reason sometimes?
You might be better off to write it like this:
private function getMangaFromName($name) {
$id = $this->generateId($name);
$mangas = new Query("SELECT * FROM tbl_manga WHERE manga_cid = '" . $this->conn->escapeString($id) . "'", $this->conn);
if($mangas->moveNext()) {
return $mangas->getRow();
} else {
if(!$mangas || $mangas->hasError()) {
logError("getMangaFromName($name): " . $this->conn->getError());
}
return null;
}
}
// Then check it like this:
$manga = $this->getMangaFromName($name);
if ( empty($manga) ) {
$manga = $this->addManga($name);
}

Categories