-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add external data manager #246
Changes from 3 commits
e323b0b
156fa7e
eb7732a
6661ed6
17dc208
902e59f
230353f
e976f08
99a39fb
e7d2f6b
3d5539f
d2c846c
385e707
d75f6d9
666d742
0b4a005
42f893a
50b3c04
fe4e40e
7ee0eb1
59fd505
2fe4dec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<?php | ||
|
||
namespace Payutc\Bom; | ||
use \Payutc\Db\Dbal; | ||
use \Payutc\Bom\User; | ||
use \Payutc\Exception\ExternalDataException; | ||
|
||
|
||
class ExternalData { | ||
|
||
protected static function addConditions($qb, $fun_id, $usr=null) { | ||
$qb->from('t_external_data_exd', 'exd') | ||
->where('fun_id = :fun_id') | ||
->setParameter('fun_id', $fun_id); | ||
if (is_int($usr) or $usr === "0" or intval($usr) != 0) { | ||
$qb->andWhere('usr_id = :usr_id') | ||
->setParameter('usr_id', $usr); | ||
} | ||
else if ($usr === null) { | ||
$qb->andWhere('usr_id is NULL'); | ||
} | ||
else { | ||
$qb->leftjoin('exd', 'ts_user_usr', 'usr', 'exd.usr_id = usr.usr_id') | ||
->andWhere('usr.usr_nickname = :login') | ||
->setParameter('login', $usr); | ||
} | ||
} | ||
|
||
protected static function insert($fun_id, $key, $val, $usr_id = null) { | ||
$conn = Dbal::conn(); | ||
$a = $conn->insert('t_external_data_exd', array( | ||
'fun_id' => $fun_id, | ||
'usr_id' => $usr_id, | ||
'exd_key' => $key, | ||
'exd_val' => $val)); | ||
} | ||
|
||
public static function get($fun_id, $key, $usr = null) { | ||
static::checkKey($key); | ||
$qb = Dbal::createQueryBuilder(); | ||
$qb->select('exd_val'); | ||
static::addConditions($qb, $fun_id, $usr); | ||
$qb->andWhere('exd_key = :exd_key') | ||
->setParameter('exd_key', $key); | ||
$res = $qb->execute()->fetch(); | ||
if ($res === false) { | ||
throw new ExternalDataException("Not found : fun=$fun_id, key=$key, usr=$usr", 404); | ||
} | ||
return $res['exd_val']; | ||
} | ||
|
||
public static function set($fun_id, $key, $val, $usr = null) { | ||
static::checkKey($key); | ||
try { | ||
static::get($fun_id, $key, $usr); | ||
} | ||
catch (ExternalDataException $e) { | ||
// data does not exist, let's create it ! | ||
if ($e->getCode() == 404) { | ||
if (!is_int($usr) and $usr !== null) { | ||
// we got the login | ||
$u = new User($usr); | ||
$usr = $u->getId(); | ||
} | ||
static::insert($fun_id, $key, $val, $usr); | ||
} | ||
} | ||
$qb = Dbal::createQueryBuilder(); | ||
$qb->update('t_external_data_exd', 'exd'); | ||
static::addConditions($qb, $fun_id, $usr); | ||
$qb->set('exd_val', "'$val'"); | ||
$res = $qb->execute(); | ||
} | ||
|
||
protected static function checkKey($key) { | ||
$pattern = '/^[a-zA-Z0-9_-]+$/'; | ||
if(preg_match($pattern, $key) === 0) { | ||
throw new ExternalDataException("Invalid key, allowed char are [a-zA-Z0-9_-]", 442); | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?php | ||
|
||
namespace Payutc\Exception; | ||
|
||
class ExternalDataException extends PayutcException {} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ public function up(Schema $schema) | |
|
||
public function down(Schema $schema) | ||
{ | ||
$this->addSql("ALTER TABLE `t_purchase_pur2` | ||
$this->addSql("ALTER TABLE `t_purchase_pur` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ça devrait être dans une autre PR, ça non ? |
||
DROP `pur_qte`, | ||
DROP `pur_unit_price`;"); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
namespace Payutc\Migrations; | ||
|
||
use Doctrine\DBAL\Migrations\AbstractMigration, | ||
Doctrine\DBAL\Schema\Schema; | ||
|
||
/** | ||
* Auto-generated Migration: Please modify to your need! | ||
*/ | ||
class Version20130921203415 extends AbstractMigration | ||
{ | ||
public function up(Schema $schema) | ||
{ | ||
$this->addSql(" | ||
CREATE TABLE IF NOT EXISTS `t_external_data_exd` ( | ||
`exd_id` int(11) NOT NULL AUTO_INCREMENT, | ||
`fun_id` int(11) unsigned NOT NULL, | ||
`usr_id` int(11) unsigned, | ||
`exd_key` varchar(128) NOT NULL, | ||
`exd_val` varchar(1024) NOT NULL, | ||
`exd_inserted` date NOT NULL, | ||
`exd_removed` date, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Les champs
|
||
PRIMARY KEY (`exd_id`), | ||
KEY `fun_id` (`fun_id`), | ||
KEY `usr_id` (`usr_id`), | ||
KEY `exd_key` (`exd_key`(127)) | ||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;"); | ||
$this->addSql(" | ||
ALTER TABLE `t_external_data_exd` | ||
ADD CONSTRAINT `t_external_data_exd_ibfk_2` FOREIGN KEY (`usr_id`) REFERENCES `ts_user_usr` (`usr_id`), | ||
ADD CONSTRAINT `t_external_data_exd_ibfk_1` FOREIGN KEY (`fun_id`) REFERENCES `t_fundation_fun` (`fun_id`), | ||
ADD UNIQUE `fun_usr_key_uniq` ( `fun_id` , `usr_id` , `exd_key` )"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actuellement lors d'une modification tu écrases l'ancienne valeur (tu ne tiens donc pas compte de ma proposition de conserver l'historique dans l'issue original). Mais en plus le jour ou on codera la suppression, ta contrainte |
||
} | ||
|
||
public function down(Schema $schema) | ||
{ | ||
$this->addSql(" | ||
DROP TABLE `t_external_data_exd`; | ||
ALTER TABLE `payutc`.`t_external_data_exd` DROP INDEX `fun_usr_key_uniq`;"); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
|
||
namespace Payutc\Service; | ||
|
||
|
||
use \Payutc\Config; | ||
use \Payutc\Log; | ||
use \Payutc\Bom\ExternalData; | ||
|
||
class DATAADMIN extends \ServiceBase { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Il manque le delete |
||
|
||
public function get($fun_id, $key, $usr_id = null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Le usr_id n'est pas manipulé par les clients, tu dois exposer des methodes avec badge_id ou login (et on utilise les deux en fonction des contextes) genre mozart va venir ajouter des infos par le badge alors qu'une billetterie en ligne viendra ajouter des données par login... |
||
$this->checkRight(true, true, true, $fun_id); | ||
return ExternalData::get($fun_id, $key, $usr_id); | ||
} | ||
|
||
public function set($fun_id, $key, $val, $usr_id = null) { | ||
$this->checkRight(true, true, true, $fun_id); | ||
return ExternalData::set($fun_id, $key, $val, $usr_id); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?php | ||
|
||
require_once 'bootstrap.php'; | ||
|
||
use \Payutc\Bom\ExternalData; | ||
|
||
|
||
class ExternalDataRodbTest extends ReadOnlyDatabaseTest { | ||
|
||
|
||
public function getDataSet() | ||
{ | ||
return $this->computeDataset(array( | ||
'fundations.yml', | ||
'users.yml', | ||
'externaldata.yml' | ||
)); | ||
} | ||
|
||
/** | ||
* @requires PHP 5.4 | ||
*/ | ||
public function testGetUserData() | ||
{ | ||
$a = ExternalData::get(1, 'key-user', 1); | ||
$this->assertEquals('value1', $a); | ||
$a = ExternalData::get(1, 'key-user', 'trecouvr'); | ||
$this->assertEquals('value1', $a); | ||
} | ||
|
||
public function testGetFunData() | ||
{ | ||
$a = ExternalData::get(1, 'key-fun'); | ||
$this->assertEquals('value2', $a); | ||
} | ||
|
||
public function testGetUsrDataCastArg() | ||
{ | ||
$a = ExternalData::get(1, 'key-user', "1"); | ||
$this->assertEquals('value1', $a); | ||
} | ||
|
||
/** | ||
* Test get throw an exception when the key does not exist | ||
* | ||
* @expectedException \Payutc\Exception\ExternalDataException | ||
* @expectedExceptionCode 404 | ||
*/ | ||
public function testGetUserDataWhichDoesNotExist() | ||
{ | ||
ExternalData::get(1, 'key-no-exist', 1); | ||
} | ||
|
||
/** | ||
* Test get throw an exception when the key does not exist | ||
* | ||
* @expectedException \Payutc\Exception\ExternalDataException | ||
* @expectedExceptionCode 404 | ||
*/ | ||
public function testGetFunDataWhichDoesNotExist() | ||
{ | ||
ExternalData::get(1, 'key-no-exist'); | ||
} | ||
|
||
public function testGetFunDataWithSimilarKeyThanUser() | ||
{ | ||
$a = ExternalData::get(1, 'key-user'); | ||
$this->assertEquals('value3', $a); | ||
} | ||
|
||
} | ||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<?php | ||
|
||
|
||
require_once 'bootstrap.php'; | ||
|
||
use \Payutc\Bom\ExternalData; | ||
|
||
|
||
class ExternalDataRwdbTest extends ReadOnlyDatabaseTest { | ||
|
||
|
||
public function getDataSet() | ||
{ | ||
return $this->computeDataset(array( | ||
'fundations.yml', | ||
'users.yml', | ||
'externaldata.yml' | ||
)); | ||
} | ||
|
||
|
||
public function testSetUsrData() | ||
{ | ||
$a = ExternalData::get(1, 'key-user', 1); | ||
ExternalData::set(1, 'key-user', $a.'-newvalue', 1); | ||
$b = ExternalData::get(1, 'key-user', 1); | ||
$this->assertEquals($a.'-newvalue', $b); | ||
} | ||
|
||
public function testSetFunData() | ||
{ | ||
$orig_user = ExternalData::get(1, 'key-user', 1); | ||
$orig_fun = ExternalData::get(1, 'key-user', 1); | ||
$a = ExternalData::get(1, 'key-fun'); | ||
ExternalData::set(1, 'key-fun', $a.'-newvalue'); | ||
$b = ExternalData::get(1, 'key-fun'); | ||
$this->assertEquals($a.'-newvalue', $b); | ||
// check that this does not affect the others | ||
$this->assertEquals($orig_user, ExternalData::get(1, 'key-user', 1)); | ||
$this->assertEquals($orig_fun, ExternalData::get(1, 'key-user', 1)); | ||
} | ||
|
||
public function testSetFunData2() | ||
{ | ||
$orig_user = ExternalData::get(1, 'key-user', 1); | ||
$orig_fun = ExternalData::get(1, 'key-user', 1); | ||
$a = ExternalData::get(1, 'key-user'); | ||
ExternalData::set(1, 'key-user', $a.'-newvalue'); | ||
$b = ExternalData::get(1, 'key-user'); | ||
$this->assertEquals($a.'-newvalue', $b); | ||
// check that this does not affect the others | ||
$this->assertEquals($orig_user, ExternalData::get(1, 'key-user', 1)); | ||
$this->assertEquals($orig_fun, ExternalData::get(1, 'key-user', 1)); | ||
} | ||
|
||
public function testSetUsrDataInsert() | ||
{ | ||
ExternalData::set(1, 'key-user-2', 'myvalue', 1); | ||
$a = ExternalData::get(1, 'key-user-2', 1); | ||
$this->assertEquals('myvalue', $a); | ||
} | ||
|
||
public function testSetFunDataInsert() | ||
{ | ||
ExternalData::set(1, 'key-fun-2', 'myvalue-fun'); | ||
$a = ExternalData::get(1, 'key-fun-2'); | ||
$this->assertEquals('myvalue-fun', $a); | ||
} | ||
|
||
/** | ||
* Test set throw an exception when the key is invalide | ||
* | ||
* @expectedException \Payutc\Exception\ExternalDataException | ||
* @expectedExceptionCode 442 | ||
*/ | ||
public function testSetDataOnInvalidKey() | ||
{ | ||
ExternalData::set(1, 'key fun 2', 'myvalue-fun'); | ||
} | ||
|
||
/** | ||
* Test set throw an exception when the key is invalide | ||
* | ||
* @expectedException \Payutc\Exception\ExternalDataException | ||
* @expectedExceptionCode 442 | ||
*/ | ||
public function testSetDataOnInvalidKey2() | ||
{ | ||
ExternalData::set(1, 'key\'', 'myvalue-fun'); | ||
} | ||
|
||
/** | ||
* Test get throw an exception when the key is invalide | ||
* | ||
* @expectedException \Payutc\Exception\ExternalDataException | ||
* @expectedExceptionCode 442 | ||
*/ | ||
public function testGetDataOnInvalidKey() | ||
{ | ||
ExternalData::get(1, 'key fun 2'); | ||
} | ||
|
||
/** | ||
* Test get throw an exception when the key is invalide | ||
* | ||
* @expectedException \Payutc\Exception\ExternalDataException | ||
* @expectedExceptionCode 442 | ||
*/ | ||
public function testGetDataOnInvalidKey2() | ||
{ | ||
ExternalData::get(1, 'key\''); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
En gros quand il y'a un insert, tu reupdates derrière... ça fait une requête inutile, c'est donc non performant...