I'm looking to implement a cache within Zend_Db, there isn't any native method to provide a cache to Zend_Db, so I'm wondering where should I do it.
I took a look to the Zend_Db_Table_Abstract (I'm extending it in a custom App_Model_DbTable_Abstract) and I found a protected method _fetch() which directly take a Zend_Db_Table_Select instance and looks like to be the last step before the adapter.
I was thinking override this method, serialize the $select object, hash it, and finally cache it, and check against each $select object provided to return the cache or an up-to-date rowset.
Is it a correct way to do?
Here is what I just did:
class App_Model_DbTable_Abstract extends Zend_Db_Table_Abstract
{
protected function _fetch(Zend_Db_Table_Select $select)
{
$hashedQuery = sha1(serialize($select->__toString()));
$cacheManager = Zend_Registry::get('Zend_Cache_Manager');
$cache = $cacheManager->getCache('database');
if (!($data = $cache->load($hashedQuery))) {
$data = parent::_fetch($select);
$cache->save($data, $hashedQuery);
}
return $data;
}
}
As far as I know, the zf create db-table <name> will always create a class inheriting Zend_Db_Table_Abstract which would make your proposal difficult to manage.
Besides, you're coupling the cache & db modules of ZF so one could argue that it's not right to place cache mechanisms under the dbtable scope. For example: you should not know where the data is being fetched from but still be able to cache it, so the process becomes this:
check cache for data, serve if found
fetch data from X (could be dbtable, could also be a Service, an XML-file, some JSON etc)
save data in cache and serve data
So although your solution makes sense now since you're only using dbtable models, it could be placed in a more suiting layer. I would check out http://www.slideshare.net/weierophinney/playdoh-modelling-your-objects-1766001 (around slide #35) for a practical solution.
Summary: the dbtable module and your code concerning it should always be about using the db.
public function indexAction()
{
// action body
$this->_helper->layout->setLayout('layout');
$db = new Zend_Db_Adapter_Pdo_Mysql(array('host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'zendtest'));
$sql = "SELECT SQL_CALC_FOUND_ROWS "
. " register.firstname, "
. " register.lastname, "
. " register.username, "
. " register.password, "
. " register.email, "
. " register.city, "
. " register.state, "
. " register.contactno "
. " FROM register register "
. " WHERE register.id = ? ";
$result = $db->fetchall($sql,1);
$result1 = "";
$cache = Zend_Registry::get('cache');
if(!$result1 = $cache->load('mydata2')) {
echo 'caching the data…..';
$cache->save($result, 'mydata2');
} else {
echo 'retrieving cache data…….';
Zend_Debug::dump($result1);
}
}
define cache array in bootstrap file then using zend DB get the data from the database and store it in cache...
next time you don't need to get data from db . you can easily and fast access that data from the cache.
Related
I have written an update query in TYPO3, Now I need to change it to query-object repository method. How to change the code below?
public function updatePaymentDetails($uid, $txnID, $amt, $stats)
{
$itemUID = $uid;
$transID = $txnID;
$amountPaid = $amt;
$txStatus = $stats;
$tableName = 'tx_paypalpayment_domain_model_transactions AS tpp';
$whereCondition = 'tpp.uid=' . '"' . $itemUID . '"';
$setValues = ['transactionid' => $transID, 'amount' => $amountPaid, 'txnstatus' => $txStatus];
$result = $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tableName, $whereCondition, $setValues);
return $result;
}
I created this much in my own idea (don't know it is correct or not), What should be the remaining portion?
public function paymentUpdate($uid, $txnID, $amt, $stats) {
$query = $this->createQuery();
$query->matching(
$query->logicalAnd(
$query->equals("transactionid", $txnID),
$query->equals("amount", $amt),
$query->equals("txnstatus", $stats)
)
);
/*--- Update Code ---*/
return $query->execute();
}
Is there any way to do that?
The TYPO3/Extbase way is to first fetch your transaction from the persistence layer then apply your changes to the domain object and then update it in your repository.
Something like below in your controller action:
$transaction = $this->transactionRepository->findByIdentifier($itemUid);
$transaction->setTransactionId($transID);
$transaction->setAmount($amountPaid);
$transaction->setStatus($txStatus);
$this->transactionRepository->update($transaction);
If you wants to do a direct update instead of first fetching the record then take a look at the \TYPO3\CMS\Core\Database\Query\QueryBuilder (Only exists in newer versions of TYPO3 - 8.7 and above). In older versions of TYPO3 you could take a look at $GLOBALS['TYPO3_DB']->exec_*.
I am trying to insert record into my database using moodle.
I am using version 1.9.19. i am trying the following code :
<?php
require_once('config.php');
require_once('uplo.php');
$mform = new uplo();
$mform->display();
if(isset($_POST['submitbutton'])){
$name = $mform->get_data('name');
$email = $mform->get_data('email');
$table='mdl_tet';
$res=insert_record($table, '$name','$email') ;
}
?>
But this is not working correctly. How to do that correctly.
Note : Why am using 1.9.19 means my client using this version so i cant change the version.
The insert_record() function takes two parameters - the name of the table (without the prefix) and an object containing the data to insert into the table.
So, in this case, you should write something like:
$ins = (object)array('name' => $name, 'email' => $email);
$ins->id = insert_record('tet', $ins);
OR:
$ins = new stdClass();
$ins->name = $name;
$ins->email = $email;
$ins->id = insert_record('tet', $ins);
(As an aside - make sure you turn on debugging - https://docs.moodle.org/19/en/Debugging - it will make your life a lot easier).
i'm experimenting with elasticsearch within mojolicious.
I'm reasonably new at both.
I wanted to create a helper to store the ES connection and I was hoping to pass the helper configuration relating to ES (for example the node info, trace_on file etc).
If I write the following very simple helper, it works;
has elasticsearch => sub {
return Search::Elasticsearch->new( nodes => '192.168.56.21:9200', trace_to => ['File','/tmp/elasticsearch.log'] );
};
and then in startup
$self->helper(es => sub { $self->app->elasticsearch() });
however if I try to extend that to take config - like the following -
it fails. I get an error "cannot find index on package" when the application calls $self->es->index
has elasticsearch => sub {
my $config = shift;
my $params->{nodes} = '192.168.56.21:' . $config->{port};
$params->{trace_to} = $config->{trace_to} if $config->{trace_to};
my $es = Search::Elasticsearch->new( $params );
return $es;
};
and in startup
$self->helper(es => sub { $self->app->elasticsearch($self->config->{es}) });
I assume I'm simply misunderstanding helpers or config or both - can someone enlighten me?
Just fyi, in a separate controller file I use the helper as follows;
$self->es->index(
index => $self->_create_index_name($index),
type => 'crawl_data',
id => $esid,
body => {
content => encode_json $data,
}
);
that works fine if I create the helper using the simple (1st) form above.
I hope this is sufficient info? please let me know if anything else is required?
First of all, has and helper are not the same. has is a lazily built instance attribute. The only argument to an attribute constructor is the instance. For an app, it would look like:
package MyApp;
has elasticsearch => sub {
my $app = shift;
Search::ElasticSearch->new($app->config->{es});
};
sub startup {
my $app = shift;
...
}
This instance is then persistent for the life of the application after first use. I'm not sure if S::ES has any reconnect-on-drop logic, so you might need to think about it a permanent object is really what you want.
In contrast a helper is just a method, available to the app, all controllers and all templates (in the latter case, as a function). The first argument to a helper is a controller instance, whether the current one or a new one, depending on context. Therefore you need to build your helper like:
has (elasticsearch => sub {
my ($c, $config) = #_;
$config ||= $c->app->config->{es};
Search::ElasticSearch->new($config);
});
This mechanism will build the instance on demand and can accept pass-in arguments, perhaps for optional configuration override as I have shown in that example.
I hope this answers your questions.
I'm absolutely new to Slim Framework. I'm working on an Webservice that should provide an interface between an Android App and a Web-Application. I used the Slim Documentation to make my first steps and now I want to create a simple GET route, to receive information from the App. Here is what I have so far:
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$name_outside = '';
$app = new \Slim\Slim();
$app->get('/session/program_name/:name', function ($name) use($app) {
$name_outside = $name;
echo $name;
});
$app->run();
echo $name_outside;
I need to access the variable :name outside the function, but what I get is nothing. What I am doing wrong here?
Btw: I know that GET-routes usually are used to list existing resources, but for my simple case, I decided to use it that way.
Fix your code to hold name as args parameters ,then you can get in in Your function
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$name_outside = '';
$app = new \Slim\Slim();
$app->get('/session/program_name/{name}', function ($args) use($app) {
$name_outside = $args['name'];
echo $args['name'];
});
$app->run();
To acess the $name_outside inside the function context you pass it.
$app->get('/session/program_name/:name', function ($name) use($app, &$name_outside) {
$name_outside = $name;
echo $name;
});
But perhaps you're using Slim in a wrong way. Why you have to access the variable outside of your route?
No code is execyted after the run() call. That's the way slim works, try to put a die where you're echo the variable, it isn't reachable.
You shouldn't have the need to access the context of the route outside of it this way. To transform a request or a response you use middlewares with the hooks.
Does any know of a way to integrate zend framework with Mongo using Doctrine 2 beta ODM?
I've viewed the zendcast video on integrating with Doctrine 2 ORM for MySQL but Bisna was never updated to support Mongo.
I guess I can try and hack Bisna to get it working but I'd like to know if someone else has already found a way to get it working.
It's pretty easy to write a Zend Bootstrap Resource.
Here is one I use:
<?php
namespace Cob\Application\Resource;
use Doctrine\Common\Annotations\AnnotationReader,
Doctrine\ODM\MongoDB\DocumentManager,
Doctrine\MongoDB\Connection,
Doctrine\ODM\MongoDB\Configuration,
Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver,
Doctrine\Common\EventManager;
/**
* Creates a MongoDB connection and DocumentManager instance
*
* #author Andrew Cobby <cobby#cobbweb.me>
*/
class Mongo extends \Zend_Application_Resource_ResourceAbstract
{
/**
* #return \Doctrine\ODM\MongoDB\DocumentManager
*/
public function init()
{
$options = $this->getOptions() + array(
'defaultDB' => 'my_database',
'proxyDir' => APPLICATION_PATH . '/domain/Proxies',
'proxyNamespace' => 'Application\Proxies',
'hydratorDir' => APPLICATION_PATH . '/domain/Hydrators',
'hydratorNamespace' => 'Application\Hydrators'
);
$config = new Configuration();
$config->setProxyDir($options['proxyDir']);
$config->setProxyNamespace($options['proxyNamespace']);
$config->setHydratorDir($options['hydratorDir']);
$config->setHydratorNamespace($options['hydratorNamespace']);
$config->setDefaultDB($options['defaultDB']);
$reader = new AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ODM\MongoDB\Mapping\\');
$config->setMetadataDriverImpl(new AnnotationDriver($reader, $this->getDocumentPaths()));
$evm = new EventManager();
$evm->addEventSubscriber(new SlugSubscriber());
return DocumentManager::create(new Connection(), $config, $evm);
}
public function getDocumentPaths()
{
$paths = array();
foreach(new \DirectoryIterator(APPLICATION_PATH . '/modules') as $module){
$path = $module->getPathname() . '/src/Domain/Document';
if((!$module->isDir() || $module->isDot()) || !is_dir($path)){
continue;
}
$paths[] = $path;
}
if(!count($paths)){
throw new \Exception("No document paths found");
}
return $paths;
}
}
Though you'll have to update the getDocumentPaths() method to suit your application directory structure.
I wrote my own very simple application resource plugin and container, using Guilherme's integration suite for inspiration.
I'm sure this could be much more featured in terms of capturing options but I figured I'll add those in as I need them.
See https://gist.github.com/891415