Skip to content

Commit

Permalink
Added created to db tables, new edge/data syntax, others (#8)
Browse files Browse the repository at this point in the history
* Added created to db tables, new edge/data syntax, others

* [CodeFactor] Apply fixes

* Added unit test, updated some examples of new edge syntax
  • Loading branch information
mikeland73 authored Apr 1, 2019
1 parent f02f9ef commit 4ef2c08
Show file tree
Hide file tree
Showing 20 changed files with 194 additions and 33 deletions.
37 changes: 34 additions & 3 deletions .phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,35 @@
</properties>

<rule ref="Squiz.Arrays.ArrayBracketSpacing"/>
<rule ref="Squiz.Arrays.ArrayDeclaration"/>
<rule ref="Squiz.Arrays.ArrayDeclaration.DoubleArrowNotAligned">
<severity>0</severity>
</rule>
<rule ref="Squiz.Arrays.ArrayDeclaration.ValueNotAligned">
<severity>0</severity>
</rule>
<rule ref="Squiz.Arrays.ArrayDeclaration.KeyNotAligned">
<severity>0</severity>
</rule>
<rule ref="Squiz.Arrays.ArrayDeclaration.SingleLineNotAllowed">
<severity>0</severity>
</rule>
<rule ref="Squiz.Arrays.ArrayDeclaration.MultiLineNotAllowed">
<severity>0</severity>
</rule>
<rule ref="Squiz.Arrays.ArrayDeclaration.CloseBraceNotAligned">
<severity>0</severity>
</rule>
<rule ref="Squiz.Classes.ClassFileName"/>
<rule ref="Squiz.Classes.ValidClassName"/>
<rule ref="Squiz.ControlStructures.ControlSignature">
<properties>
<property name="requiredSpacesBeforeColon" value="0" />
</properties>
<exclude-pattern>/app/views/**</exclude-pattern>
<exclude-pattern>/sample_app/views/**</exclude-pattern>
</rule>
<rule ref="Squiz.ControlStructures.ElseIfDeclaration">
<exclude-pattern>/app/views/**</exclude-pattern>
<exclude-pattern>/sample_app/views/**</exclude-pattern>
</rule>
<rule ref="Squiz.Commenting.BlockComment"/>
<rule ref="Squiz.Commenting.DocCommentAlignment"/>
Expand Down Expand Up @@ -47,11 +64,17 @@
</rule>
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace"/>
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<rule ref="Generic.Arrays.ArrayIndent">
<properties>
<property name="indent" value="2" />
</properties>
</rule>
<rule ref="Generic.Classes.OpeningBraceSameLine"/>
<rule ref="Generic.Commenting.Todo"/>
<rule ref="Generic.ControlStructures.InlineControlStructure"/>
<rule ref="Generic.Formatting.DisallowMultipleStatements"/>
<rule ref="Generic.Formatting.SpaceAfterCast"/>
<rule ref="Generic.Functions.FunctionCallArgumentSpacing"/>
<rule ref="Generic.NamingConventions.ConstructorName"/>
<rule ref="Generic.PHP.DeprecatedFunctions"/>
<rule ref="Generic.PHP.LowerCaseKeyword"/>
Expand All @@ -67,7 +90,6 @@
<rule ref="PSR2.Files.EndFileNewline"/>
<rule ref="Zend.Files.ClosingTag">
<exclude-pattern>/app/views/**</exclude-pattern>
<exclude-pattern>/sample_app/views/**</exclude-pattern>
</rule>

<!-- PEAR uses warnings for inline control structures, so switch back to errors -->
Expand All @@ -77,5 +99,14 @@
</properties>
</rule>

<!-- <arg name="tab-width" value="2"/> -->

<rule ref="PEAR.WhiteSpace.ScopeIndent">
<properties>
<property name="indent" value="2" />
<property name="ignoreIndentationTokens" type="array"
value="T_COMMENT,T_DOC_COMMENT_OPEN_TAG"/>
</properties>
<exclude-pattern>/app/views/**</exclude-pattern>
</rule>
</ruleset>
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ Define nodes (your model) with minimum boilerplate
class User extends GPNode {
protected static function getDataTypesImpl() {
return [
new GPDataType('name', GPDataType::GP_STRING, true),
GPDataType::string('name', $indexed = true),
];
}
protected static function getEdgeTypesImpl() {
return [
new GPEdgeType(BankAccount::class),
BankAccount::edge(),
];
}
}
Expand Down
2 changes: 1 addition & 1 deletion graphp/core/GPConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __get($name) {
if (isset($this->config[$name])) {
return $this->config[$name];
}
throw new Exception($name.' is not in '.$this->name.' config' , 1);
throw new Exception($name.' is not in '.$this->name.' config', 1);
}

public static function from_file($file) {
Expand Down
21 changes: 16 additions & 5 deletions graphp/core/GPDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

class GPDatabase extends GPObject {

const LIMIT = 100;
public const LIMIT = 100;

private const NODE_SELECT =
'SELECT id, type, data, UNIX_TIMESTAMP(created) AS created, UNIX_TIMESTAMP(updated) AS updated';

private static $dbs = [];
private $connection;
Expand Down Expand Up @@ -103,15 +106,15 @@ public function updateNodeData(GPNode $node) {
public function getNodeByID($id) {
return queryfx_one(
$this->getConnection(),
'SELECT * FROM node WHERE id = %d;',
self::NODE_SELECT.' FROM node WHERE id = %d;',
$id
);
}

public function getNodeByIDType($id, $type) {
return queryfx_one(
$this->getConnection(),
'SELECT * FROM node WHERE id = %d AND type = %d;',
self::NODE_SELECT.' FROM node WHERE id = %d AND type = %d;',
$id,
$type
);
Expand All @@ -125,11 +128,19 @@ public function multigetNodeByIDType(array $ids, $type = null) {
$args = array_filter([$ids, $type]);
return queryfx_all(
$this->getConnection(),
'SELECT * FROM node WHERE id IN (%Ld) '.$type_fragment,
self::NODE_SELECT.' FROM node WHERE id IN (%Ld) '.$type_fragment,
...$args
);
}

public function getNodeIDsByTypeDataAll(int $type): array {
return ipull(queryfx_all(
$this->getConnection(),
'SELECT node_id FROM node_data WHERE type = %d;',
$type
), 'node_id');
}

public function getNodeIDsByTypeData($type, array $data) {
if (!$data) {
return [];
Expand Down Expand Up @@ -315,7 +326,7 @@ public function getConnectedNodeCount(array $nodes, array $edges) {
public function getAllByType($type, $limit, $offset) {
return queryfx_all(
$this->getConnection(),
'SELECT * FROM node WHERE type = %d ORDER BY updated DESC LIMIT %d, %d;',
self::NODE_SELECT.' FROM node WHERE type = %d ORDER BY updated DESC LIMIT %d, %d;',
$type,
$offset,
$limit
Expand Down
8 changes: 8 additions & 0 deletions graphp/core/GPLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public static function return404() {
$config = GPConfig::get();
if (GP::isAjax() || GP::isJSONRequest()) {
GP::ajax(['error_code' => 404, 'error' => 'Resource Not Found']);
} else if ($config->redirect_404) {
header('Location: '.$config->redirect_404, true);
} else if ($config->view_404 && $config->layout_404) {
GP::viewWithLayout($config->view_404, $config->layout_404);
} else if ($config->view_404) {
Expand Down Expand Up @@ -138,6 +140,12 @@ public static function ajax(array $data) {
header('Pragma: no-cache');
header('Content-type: application/json');
echo json_encode($data);
GP::exit();
}

public static function exit() {
GPDatabase::disposeALl();
exit();
}

public static function addGlobal($key, $val) {
Expand Down
7 changes: 5 additions & 2 deletions graphp/db/mysql_schema.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

CREATE DATABASE IF NOT EXISTS graphp;
CREATE DATABASE IF NOT EXISTS graphp;

USE graphp;

Expand All @@ -26,6 +26,7 @@ CREATE TABLE IF NOT EXISTS `edge` (
`from_node_id` bigint(20) unsigned NOT NULL,
`to_node_id` bigint(20) unsigned NOT NULL,
`type` bigint(20) unsigned NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`from_node_id`,`to_node_id`,`type`),
KEY `from_type_updated` (`from_node_id`,`type`,`updated`),
Expand All @@ -42,6 +43,7 @@ CREATE TABLE IF NOT EXISTS `node` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`type` bigint(20) unsigned NOT NULL,
`data` text COLLATE utf8_unicode_ci NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `type_updated` (`type`,`updated`)
Expand All @@ -57,6 +59,7 @@ CREATE TABLE IF NOT EXISTS `node_data` (
`node_id` bigint(20) unsigned NOT NULL,
`type` bigint(20) unsigned NOT NULL,
`data` text COLLATE utf8_unicode_ci NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`node_id`,`type`),
KEY `type_data` (`type`,`data`(128)),
Expand All @@ -82,4 +85,4 @@ ALTER TABLE `node_data`

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
2 changes: 1 addition & 1 deletion graphp/lib/GPRouteGenerator.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

class GPRouteGenerator extends GPObject {
class GPRouteGenerator extends GPObject {

private $path;
private $controller;
Expand Down
2 changes: 2 additions & 0 deletions graphp/model/GPDataType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

class GPDataType extends GPObject {

use GPDataTypeCreator;

const GP_INT = 'is_int';
const GP_NODE_ID = 'is_int';
const GP_FLOAT = 'is_float';
Expand Down
2 changes: 1 addition & 1 deletion graphp/model/GPEdgeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function setFromClass($from_class) {

public function getType() {
if (!$this->type) {
$this->type = STRUtils::to64BitInt($this->getStorageKey());
$this->type = STRUtils::to64BitInt($this->getStorageKey());
}
return $this->type;
}
Expand Down
10 changes: 10 additions & 0 deletions graphp/model/GPNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ abstract class GPNode extends GPObject {
use GPNodeLoader;
use GPNodeMagicMethods;
use GPBatchLoader;
use GPNodeEdgeCreator;

private
$data,
$id,
$updated,
$created,
// array([edge_type] => [array of nodes indexed by id])
$connectedNodeIDs = [],
$connectedNodes = [],
Expand All @@ -35,10 +37,18 @@ public function getID() {
return (int) $this->id;
}

public function isSaved(): bool {
return $this->getID() > 0;
}

public function getUpdated() {
return $this->updated;
}

public function getCreatedTimestamp() {
return $this->created;
}

public static function getType() {
return STRUtils::to64BitInt(static::getStorageKey());
}
Expand Down
31 changes: 26 additions & 5 deletions graphp/model/GPNodeLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ private static function nodeFromArray(array $data) {
$node = new $class(json_decode($data['data'], true));
$node->id = $data['id'];
$node->updated = $data['updated'];
$node->created = $data['created'];
return $node;
}

Expand Down Expand Up @@ -70,22 +71,37 @@ public static function __callStatic($name, array $arguments) {
} else if (substr_compare($name, 'getOneBy', 0, 8) === 0) {
$type_name = strtolower(mb_substr($name, 8));
$only_one = true;
} else if (substr_compare($name, 'getAllWith', 0, 10) === 0) {
$type_name = strtolower(mb_substr($name, 10));
$get_all_with_type = true;
}

if (isset($type_name)) {
$class = get_called_class();
$data_type = static::getDataTypeByName($type_name);
Assert::truthy($data_type, $name.' is not a method on '.$class);
if (isset($range)) {
$required_args = 2;
} else if (isset($get_all_with_type)) {
$required_args = 0;
} else {
$required_args = 1;
}
Assert::truthy(
isset($range) ? count($arguments) >= 2 : count($arguments) === 1,
GPErrorText::wrongArgs($class, $name, 1, count($arguments))
count($arguments) >= $required_args,
GPErrorText::wrongArgs($class, $name, $required_args, count($arguments))
);
$arg = idx0($arguments);
foreach (make_array($arg) as $val) {
$data_type->assertValueIsOfType($val);
if ($arguments) {
$arg = idx0($arguments);
foreach (make_array($arg) as $val) {
$data_type->assertValueIsOfType($val);
}
}
if (isset($range)) {
array_unshift($arguments, $data_type->getIndexedType());
$results = self::getByIndexDataRange($arguments);
} else if (isset($get_all_with_type)) {
$results = self::getByIndexDataAll($data_type->getIndexedType());
} else {
$results = self::getByIndexData($data_type->getIndexedType(), $arg);
}
Expand Down Expand Up @@ -113,6 +129,11 @@ public static function unsetFromCache($id) {
unset(self::$cache[$id]);
}

private static function getByIndexDataAll($data_type) {
$node_ids = GPDatabase::get()->getNodeIDsByTypeDataAll($data_type);
return self::multiGetByID($node_ids);
}

private static function getByIndexData($data_type, $data) {
$db = GPDatabase::get();
$node_ids = $db->getNodeIDsByTypeData($data_type, make_array($data));
Expand Down
32 changes: 32 additions & 0 deletions graphp/model/traits/GPDataTypeCreator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

trait GPDataTypeCreator {

public static function array($name, ...$args) {
return new GPDataType($name, GPDataType::GP_ARRAY, ...$args);
}

public static function string($name, ...$args) {
return new GPDataType($name, GPDataType::GP_STRING, ...$args);
}

public static function bool($name, ...$args) {
return new GPDataType($name, GPDataType::GP_BOOL, ...$args);
}

public static function int($name, ...$args) {
return new GPDataType($name, GPDataType::GP_INT, ...$args);
}

public static function float($name, ...$args) {
return new GPDataType($name, GPDataType::GP_FLOAT, ...$args);
}

public static function number($name, ...$args) {
return new GPDataType($name, GPDataType::GP_NUMBER, ...$args);
}

public static function any($name, ...$args) {
return new GPDataType($name, GPDataType::GP_ANY, ...$args);
}
}
15 changes: 15 additions & 0 deletions graphp/model/traits/GPNodeEdgeCreator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

trait GPNodeEdgeCreator {

public static function edge(string $name = null) {
return new GPEdgeType(get_called_class(), $name ?: STR::pluralize(get_called_class()));
}

public static function singleEdge(string $single_name = null, string $plural_name = null) {
$defaulted_single_name = $single_name ?: get_called_class();
$defaulted_plural_name = $plural_name ?: STR::pluralize($defaulted_single_name);
return (new GPEdgeType(get_called_class(), $defaulted_plural_name))
->setSingleNodeName($defaulted_single_name);
}
}
Loading

0 comments on commit 4ef2c08

Please sign in to comment.