Skip to content

Commit

Permalink
[ENHANCEMENT] Add support for the READS SQL DATA property for custom …
Browse files Browse the repository at this point in the history
…function migrations. (#16)
  • Loading branch information
Glenn-Ewing authored Jul 30, 2020
1 parent ba69791 commit e02b21a
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 5 deletions.
28 changes: 27 additions & 1 deletion src/FunctionMigration.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ final class FunctionMigration
*/
private $deterministic;

/**
* @var bool
*/
private $readsSqlData;

/**
* @var ParameterOperation[]
*/
Expand Down Expand Up @@ -85,6 +90,7 @@ public static function drop(string $name): FunctionMigration
* @param string $operation
* @param ReturnTypeOperation $returnType
* @param bool $deterministic
* @param bool $readsSqlData
* @param array $parameterOperations
* @param array $variableOperations
* @param string|null $body
Expand All @@ -94,6 +100,7 @@ private function __construct(
string $operation,
ReturnTypeOperation $returnType = null,
bool $deterministic = false,
bool $readsSqlData = false,
array $parameterOperations = [],
array $variableOperations = [],
string $body = null
Expand All @@ -102,13 +109,14 @@ private function __construct(
$this->operation = $operation;
$this->returnType = $returnType;
$this->deterministic = $deterministic;
$this->readsSqlData = $readsSqlData;
$this->parameterOperations = $parameterOperations;
$this->variableOperations = $variableOperations;
$this->body = $body;
}

/**
* Pushes a new add parameter operation.
* Sets determinism for the function.
*
* @param bool $deterministic
* @return $this
Expand All @@ -124,6 +132,23 @@ public function isDeterministic(bool $deterministic): FunctionMigration
return $this;
}

/**
* Sets the reads sql data property of the function.
*
* @param bool $readsSqlData
* @return $this
*/
public function readsSqlData(bool $readsSqlData): FunctionMigration
{
if ($this->operation === FunctionOperation::DROP) {
throw new LogicException('Cannot set readsSqlData property in a drop migration.');
}

$this->readsSqlData = $readsSqlData;

return $this;
}

/**
* Sets the return type of the migration.
*
Expand Down Expand Up @@ -224,6 +249,7 @@ public function getOperation(): FunctionOperation
$this->operation,
$this->returnType,
$this->deterministic,
$this->readsSqlData,
$this->parameterOperations,
$this->variableOperations,
$this->body
Expand Down
18 changes: 18 additions & 0 deletions src/Operation/FunctionOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ class FunctionOperation extends AbstractOperation
*/
private $deterministic;

/**
* @var bool
*/
private $readsSqlData;

/**
* @var ParameterOperation[]
*/
Expand All @@ -47,6 +52,7 @@ class FunctionOperation extends AbstractOperation
* @param string $operation
* @param ReturnTypeOperation|null $returnType
* @param bool $deterministic
* @param bool $readsSqlData
* @param array $parameterOperations
* @param array $variableOperations
* @param string|null $body
Expand All @@ -56,6 +62,7 @@ public function __construct(
string $operation,
ReturnTypeOperation $returnType = null,
bool $deterministic = false,
bool $readsSqlData = false,
array $parameterOperations = [],
array $variableOperations = [],
string $body = null
Expand All @@ -64,6 +71,7 @@ public function __construct(
$this->operation = $operation;
$this->returnType = $returnType ?? new ReturnTypeOperation('string', ReturnTypeOperation::ADD);
$this->deterministic = $deterministic;
$this->readsSqlData = $readsSqlData;
$this->parameterOperations = $parameterOperations;
$this->variableOperations = $variableOperations;
$this->body = $body;
Expand Down Expand Up @@ -147,6 +155,16 @@ public function getDeterministic(): bool
return $this->deterministic;
}

/**
* Returns the readsSqlData flag.
*
* @return bool
*/
public function getReadsSqlData(): bool
{
return $this->readsSqlData;
}

/**
* Returns the parameter operations.
*
Expand Down
12 changes: 10 additions & 2 deletions src/Statement/MysqlStatementBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class MysqlStatementBuilder extends StatementBuilder
)
RETURNS %s
%s
%s
BEGIN
%s
Expand All @@ -36,6 +37,7 @@ class MysqlStatementBuilder extends StatementBuilder
)
RETURNS %s
%s
%s
BEGIN
%s
Expand Down Expand Up @@ -223,6 +225,10 @@ public function buildFunction(FunctionOperation $operation): string
? 'DETERMINISTIC'
: 'NOT DETERMINISTIC';

$readsSqlData = ($operation->getReadsSqlData())
? 'READS SQL DATA'
: '';

$variables = array_map(function(VariableOperation $variableOperation) {
return sprintf(
'DECLARE %s %s;',
Expand All @@ -238,7 +244,8 @@ public function buildFunction(FunctionOperation $operation): string
$this->buildIdentifier($operation->getName()), // NAME (for create)
implode(',', $parameters), // PARAMETERS
$returnType, // RETURN TYPE
$determinism, // [NOT] DETERMINISTIC
$determinism, // 'DETERMINISTIC' | 'NOT DETERMINISTIC'
$readsSqlData, // 'READS SQL DATA' | ''
implode('', $variables), // VARIABLES
$operation->getBody() // BODY
);
Expand All @@ -249,7 +256,8 @@ public function buildFunction(FunctionOperation $operation): string
$this->buildIdentifier($operation->getName()), // NAME (for create)
implode(',', $parameters), // PARAMETERS
$returnType, // RETURN TYPE
$determinism, // [NOT] DETERMINISTIC
$determinism, // 'DETERMINISTIC' | 'NOT DETERMINISTIC'
$readsSqlData, // 'READS SQL DATA' | ''
implode('', $variables), // VARIABLES
$operation->getBody() // BODY
);
Expand Down
3 changes: 2 additions & 1 deletion tests/Migrations/20200604_create_user_level_function.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
return Exo\FunctionMigration::create('user_level')
->withReturnType('integer')
->addParameter('inputValue', ['type' => 'integer'])
->isDeterministic(false)
->isDeterministic(true)
->readsSqlData(false)
->addVariable('suffixValue', ['length' => '20'])
->withBody('RETURN CONCAT(CAST(inputValue AS CHAR(25), suffixValue);');
9 changes: 9 additions & 0 deletions tests/Operation/FunctionOperationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public function testCreate()
$operation = new FunctionOperation('customer_level', FunctionOperation::CREATE,
new ReturnTypeOperation('string', ReturnTypeOperation::ADD),
true,
false,
[
new ParameterOperation('arg1', ParameterOperation::ADD),
new ParameterOperation('arg2', ParameterOperation::ADD, ['type' => 'integer']),
Expand All @@ -48,6 +49,7 @@ public function testCreate()
$this->assertEquals([], $operation->getReturnType()->getOptions());

$this->assertTrue($operation->getDeterministic());
$this->assertFalse($operation->getReadsSqlData());

$this->assertCount(3, $operation->getParameterOperations());

Expand Down Expand Up @@ -77,6 +79,7 @@ public function testReplace()
$base = new FunctionOperation('customer_level', FunctionOperation::CREATE,
new ReturnTypeOperation('string', ReturnTypeOperation::ADD),
true,
false,
[
new ParameterOperation('arg1', ParameterOperation::ADD),
new ParameterOperation('arg2', ParameterOperation::ADD, ['type' => 'integer']),
Expand All @@ -89,6 +92,7 @@ public function testReplace()
$new = new FunctionOperation('customer_level', FunctionOperation::REPLACE,
new ReturnTypeOperation('integer', ReturnTypeOperation::ADD),
false,
true,
[],
[],
self::BODY_TWO
Expand All @@ -103,6 +107,7 @@ public function testReplace()
$this->assertEquals([], $operation->getReturnType()->getOptions());

$this->assertFalse($operation->getDeterministic());
$this->assertTrue($operation->getReadsSqlData());

$this->assertCount(0, $operation->getParameterOperations());

Expand All @@ -116,6 +121,7 @@ public function testApplyDropToCreateOrReplace()
$base = new FunctionOperation('any_name', FunctionOperation::REPLACE,
new ReturnTypeOperation('string', ReturnTypeOperation::ADD),
true,
false,
[],
[],
self::BODY_ONE
Expand Down Expand Up @@ -147,6 +153,7 @@ public function testReverseReplace()
FunctionOperation::REPLACE,
new ReturnTypeOperation('integer', ReturnTypeOperation::ADD),
false,
true,
[
new ParameterOperation('id', ParameterOperation::ADD, []),
new ParameterOperation('email', ParameterOperation::ADD, ['type' => 'string', 'length' => 255]),
Expand All @@ -164,6 +171,7 @@ public function testReverseReplace()
FunctionOperation::REPLACE,
new ReturnTypeOperation('string', ReturnTypeOperation::ADD),
true,
false,
[
new ParameterOperation('id', ParameterOperation::ADD, ['type' => 'uuid']),
new ParameterOperation('username', ParameterOperation::ADD, ['type' => 'string', 'length' => 64])
Expand Down Expand Up @@ -205,6 +213,7 @@ public function testReverseDrop()
FunctionOperation::REPLACE,
new ReturnTypeOperation('integer', ReturnTypeOperation::ADD),
false,
true,
[
new ParameterOperation('id', ParameterOperation::ADD, []),
new ParameterOperation('email', ParameterOperation::ADD, ['type' => 'string', 'length' => 255, 'first' => true]),
Expand Down
6 changes: 5 additions & 1 deletion tests/Statement/MysqlStatementBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public function provider()
FunctionOperation::CREATE,
new ReturnTypeOperation('string', ReturnTypeOperation::ADD, ['length' => 20]),
true,
false,
[
new ParameterOperation('inputValue1', ParameterOperation::ADD, ['length' => 32]),
new ParameterOperation('inputValue2', ParameterOperation::ADD, ['length' => 32])
Expand All @@ -138,6 +139,7 @@ public function provider()
'inputValue1 VARCHAR(32),inputValue2 VARCHAR(32)',
'VARCHAR(20)',
'DETERMINISTIC',
'',
'DECLARE internalVarName1 INTEGER;DECLARE internalVarName2 INTEGER;',
'RETURN \'foo\';'
)
Expand All @@ -147,6 +149,7 @@ public function provider()
'user_defined_function',
FunctionOperation::REPLACE,
new ReturnTypeOperation('string', ReturnTypeOperation::ADD, ['length' => 20]),
false,
true,
[new ParameterOperation('anotherInputValue', ParameterOperation::ADD, ['length' => 32])],
[new VariableOperation('anotherVarName', VariableOperation::ADD, ['type' => 'integer'])],
Expand All @@ -158,7 +161,8 @@ public function provider()
'`user_defined_function`',
'anotherInputValue VARCHAR(32)',
'VARCHAR(20)',
'DETERMINISTIC',
'NOT DETERMINISTIC',
'READS SQL DATA',
'DECLARE anotherVarName INTEGER;',
'RETURN \'foo\';'
)
Expand Down

0 comments on commit e02b21a

Please sign in to comment.