Exakat\Graph\Gremlin3::query PHP Метод

query() публичный Метод

public query ( $query, $params = [], $load = [] )
    public function query($query, $params = array(), $load = array())
    {
        if ($this->status === self::UNCHECKED) {
            $this->checkConfiguration();
        }
        $getString = 'script=' . urlencode($query);
        if (!is_array($load)) {
            $load = array($load);
        }
        if (isset($params) && !empty($params)) {
            // Avoid changing arg10 to 'string'0 if query has more than 10 arguments.
            krsort($params);
            foreach ($params as $name => $value) {
                if (is_string($value) && strlen($value) > 2000) {
                    $gremlin = "{ '" . str_replace('$', '\\$', $value) . "' }";
                    // what about factorise this below?
                    $defName = 'a' . crc32($gremlin);
                    $defFileName = $this->scriptDir . $defName . '.gremlin';
                    if (file_exists($defFileName)) {
                        $query = str_replace($name, $defName . '()', $query);
                        $load[] = $defName;
                        unset($params[$name]);
                    } else {
                        $gremlin = 'def ' . $defName . '() ' . $gremlin;
                        file_put_contents($defFileName, $gremlin);
                        $query = str_replace($name, $defName . '()', $query);
                        $load[] = $defName;
                        unset($params[$name]);
                    }
                } elseif (is_array($value)) {
                    $valueList = array_map(function ($x) {
                        return addslashes($x);
                    }, $value);
                    $gremlin = "{ ['''" . implode("''','''", $valueList) . "'''] }";
                    $defName = 'a' . crc32($gremlin);
                    $defFileName = $this->scriptDir . $defName . '.gremlin';
                    if (file_exists($defFileName)) {
                        $query = str_replace($name, $defName . '()', $query);
                        $load[] = $defName;
                        unset($params[$name]);
                    } else {
                        $gremlin = 'def ' . $defName . '() ' . $gremlin;
                        if (strlen($gremlin) > 65535) {
                            $gremlin = <<<GREMLIN
def {$defName}() { 
    x = [];
    new File("{$this->scriptDir}/{$defName}.txt").each({ line -> x.push(line)});
    x; 
}
GREMLIN;
                            file_put_contents($defFileName, $gremlin);
                            file_put_contents($this->scriptDir . $defName . '.txt', implode("\n", $value));
                        } else {
                            file_put_contents($defFileName, $gremlin);
                        }
                        $query = str_replace($name, $defName . '()', $query);
                        $load[] = $defName;
                        unset($params[$name]);
                    }
                } else {
                    // a short string (less than 2000) : hardcoded
                    $query = str_replace($name, "'''" . addslashes($value) . "'''", $query);
                    unset($params[$name]);
                }
            }
            if (!empty($params)) {
                $getString .= '&params=' . urlencode(json_encode($params));
            }
        }
        $getString = 'script=' . urlencode($query);
        if (count($load) == 1) {
            $getString .= '&load=' . urlencode(array_pop($load));
        } elseif (count($load) > 1) {
            $getString .= '&load=' . implode(',', array_map('urlencode', $load));
        }
        // else (aka 0) is ignored (nothing to do)
        if (strlen($getString) > 20000) {
            echo 'Query string too big for GET (', strlen($getString), ")\n", 'Query : ', $query, "\n\n", print_r($params, true);
            die;
        }
        $ch = curl_init();
        //set the url, number of POST vars, POST data
        $headers = array('Content-Length: ' . strlen($getString), 'User-Agent: exakat', 'X-Stream: true');
        if (!empty($this->neo4j_auth)) {
            $headers[] = 'Authorization: Basic ' . $this->neo4j_auth;
        }
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_URL, 'http://' . $this->neo4j_host . '/tp/gremlin/execute?' . $getString);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        //execute post
        $result = curl_exec($ch);
        //close connection
        curl_close($ch);
        $result = json_decode($result);
        if (isset($result->errormessage)) {
            throw new \Exakat\Exceptions\GremlinException($result->errormessage, $query);
        }
        return $result;
    }

Usage Example

Пример #1
0
    public function generate($folder, $name = 'dependencies')
    {
        $graph = new Gremlin3(Config::factory());
        $links = array();
        $nodes = array('class' => array(), 'trait' => array(), 'interface' => array(), 'unknown' => array());
        $fullcode = array();
        $query = <<<GREMLIN
g.V().hasLabel("Class").map{[it.get().value("fullnspath"), it.get().value("fullcode")]}
GREMLIN;
        $res = $graph->query($query);
        foreach ($res->results as $v) {
            $names[$v[0]] = $v[1];
            $nodes['class'][] = $v[0];
        }
        $query = <<<GREMLIN
g.V().hasLabel("Trait").map{[it.get().value("fullnspath"), it.get().value("fullcode")]}
GREMLIN;
        $res = $graph->query($query);
        foreach ($res->results as $v) {
            $names[$v[0]] = $v[1];
            $nodes['trait'][] = $v[0];
        }
        $query = <<<GREMLIN
g.V().hasLabel("Interface").map{[it.get().value("fullnspath"), it.get().value("fullcode")]}
GREMLIN;
        $res = $graph->query($query);
        foreach ($res->results as $v) {
            $names[$v[0]] = $v[1];
            $nodes['interface'][] = $v[0];
        }
        $nodesId = array_flip(call_user_func_array('array_merge', array_values($nodes)));
        // static constants
        $query = <<<GREMLIN
g.V().hasLabel("Staticconstant").as('fullcode')
.out('CLASS').as('destination')
.repeat(__.in()).until(hasLabel("Class", "Trait", "Interface")).as('origin')
.select('origin', 'destination', 'fullcode').by('fullnspath').by('fullnspath').by('fullcode')
GREMLIN;
        $res = $graph->query($query);
        $total = 0;
        foreach ($res->results as $v) {
            if (!isset($nodesId[$v->origin])) {
                $nodes['unknown'][] = $v->origin;
                $nodesId[$v->origin] = count($nodes) - 1;
            }
            if (!isset($nodesId[$v->destination])) {
                $nodes['unknown'][] = $v->destination;
                $nodesId[$v->destination] = count($nodes) - 1;
            }
            $links[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = 'staticconstant';
            $fullcode[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = $v->fullcode;
            ++$total;
        }
        print "{$total} Static constants\n";
        // static property
        $query = <<<GREMLIN
g.V().hasLabel("Staticproperty").as('fullcode')
.out('CLASS').as('destination')
.repeat(__.in()).until(hasLabel("Class", "Trait", "Interface")).as('origin')
.select('origin', 'destination', 'fullcode').by('fullnspath').by('fullnspath').by('fullcode')
GREMLIN;
        $res = $graph->query($query);
        $total = 0;
        foreach ($res->results as $v) {
            if (!isset($nodesId[$v->origin])) {
                $nodes['unknown'][] = $v->origin;
                $nodesId[$v->origin] = count($nodes) - 1;
            }
            if (!isset($nodesId[$v->destination])) {
                $nodes['unknown'][] = $v->destination;
                $nodesId[$v->destination] = count($nodes) - 1;
            }
            $links[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = 'staticproperty';
            $fullcode[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = $v->fullcode;
            ++$total;
        }
        print "{$total} Static property\n";
        // Instantiation
        $query = <<<GREMLIN
g.V().hasLabel("New").as('fullcode')
.out('NEW').as('destination')
.repeat(__.in()).until(hasLabel("Class", "Trait", "Interface")).as('origin')
.select('origin', 'destination', 'fullcode').by('fullnspath').by('fullnspath').by('fullcode')
GREMLIN;
        $res = $graph->query($query);
        $total = 0;
        foreach ($res->results as $v) {
            if (!isset($nodesId[$v->origin])) {
                $nodes['unknown'][] = $v->origin;
                $nodesId[$v->origin] = count($nodes) - 1;
            }
            if (!isset($nodesId[$v->destination])) {
                $nodes['unknown'][] = $v->destination;
                $nodesId[$v->destination] = count($nodes) - 1;
            }
            $links[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = 'instanciation';
            $fullcode[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = $v->fullcode;
            ++$total;
        }
        print "{$total} New\n";
        // Typehint
        $query = <<<GREMLIN
g.V().hasLabel("Function").as('fullcode')
.out('ARGUMENTS').out("ARGUMENT").out("TYPEHINT").as('destination')
.repeat(__.in()).until(hasLabel("Class", "Trait", "Interface")).as('origin')
.select('origin', 'destination', 'fullcode').by('fullnspath').by('fullnspath').by('fullcode')

GREMLIN;
        $res = $graph->query($query);
        $total = 0;
        foreach ($res->results as $v) {
            if (!isset($nodesId[$v->origin])) {
                $nodes['unknown'][] = $v->origin;
                $nodesId[$v->origin] = count($nodes) - 1;
            }
            if (!isset($nodesId[$v->destination])) {
                $nodes['unknown'][] = $v->destination;
                $nodesId[$v->destination] = count($nodes) - 1;
            }
            $links[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = 'typehint';
            $fullcode[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = $v->fullcode;
            ++$total;
        }
        print "{$total} Typehint\n";
        // instanceof
        $query = <<<GREMLIN
g.V().hasLabel("Instanceof").as('fullcode')
.out('CLASS').as('destination')
.repeat(__.in()).until(hasLabel("Class", "Trait", "Interface")).as('origin')
.select('origin', 'destination', 'fullcode').by('fullnspath').by('fullnspath').by('fullcode')

GREMLIN;
        $res = $graph->query($query);
        $total = 0;
        foreach ($res->results as $v) {
            if (!isset($nodesId[$v[0]])) {
                $nodes['unknown'][] = $v[0];
                $nodesId[$v[0]] = count($nodes) - 1;
            }
            if (!isset($nodesId[$v[1]])) {
                $nodes['unknown'][] = $v[1];
                $nodesId[$v[1]] = count($nodes) - 1;
            }
            $links[$nodesId[$v[1]] . ' -> ' . $nodesId[$v[0]]][] = 'instanceof';
            $fullcode[$nodesId[$v[1]] . ' -> ' . $nodesId[$v[0]]][] = $v[2];
            ++$total;
        }
        print "{$total} Instanceof\n";
        // static methods
        $query = <<<GREMLIN
g.V().hasLabel("Staticmethodcall").as('fullcode')
.out('CLASS').as('destination')
.repeat(__.in()).until(hasLabel("Class", "Trait", "Interface")).as('origin')
.select('origin', 'destination', 'fullcode').by('fullnspath').by('fullnspath').by('fullcode')
GREMLIN;
        $res = $graph->query($query);
        $total = 0;
        foreach ($res->results as $v) {
            if (!isset($nodesId[$v->origin])) {
                $nodes['unknown'][] = $v->origin;
                $nodesId[$v->origin] = count($nodes) - 1;
            }
            if (!isset($nodesId[$v->destination])) {
                $nodes['unknown'][] = $v->destination;
                $nodesId[$v->destination] = count($nodes) - 1;
            }
            $links[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = 'staticmethodcall';
            $fullcode[$nodesId[$v->destination] . ' -> ' . $nodesId[$v->origin]][] = $v->fullcode;
            ++$total;
        }
        print "{$total} Static methods\n";
        // Final preparation
        // Nodes
        $colors = array('class' => 'darkorange', 'trait' => 'gold', 'interface' => 'skyblue', 'unknown' => 'gray');
        foreach ($nodes as $type => &$someNodes) {
            foreach ($someNodes as $id => &$n) {
                $n = <<<DOT
{$nodesId[$n]} [label=<<table color='white' BORDER='0' CELLBORDER='1' CELLSPACING='0' >
                          <tr>
                              <td bgcolor='{$colors[$type]}'>{$n}</td>
                          </tr>
                       </table>> shape="none"];
DOT;
            }
            unset($n);
        }
        unset($someNodes);
        //        print_r($nodes);
        // Links
        $colors = array('staticmethodcall' => 'firebrick2', 'staticconstant' => 'firebrick2', 'staticproperty' => 'firebrick2', 'instanceof' => 'chartreuse4', 'typehint' => 'chartreuse4', 'use' => 'darkgoldenrod2', 'instanciation' => 'black');
        $linksDot = array();
        foreach ($links as $link => $type) {
            foreach ($type as $id => $t) {
                $linksDot[] = $link . ' [shape="none" color="' . $colors[$t] . '" label="' . str_replace('"', '\\"', $fullcode[$link][$id]) . '"];';
            }
        }
        unset($type);
        $dot = "digraph graphname {\n        \n        fontname = \"Bitstream Vera Sans\"\n        fontsize = 14\n        colorscheme = \"bugn9\"\n\n        node [\n                fontname = \"Bitstream Vera Sans\"\n                fontsize = 14\n                shape = \"record\"\n        ]\n\n        edge [\n                fontname = \"Bitstream Vera Sans\"\n                fontsize = 8\n                arrowhead = \"empty\"\n                width = \"2\"\n        ]\n        \n        " . implode("\n", $nodes['class']) . "\n" . implode("\n", $nodes['trait']) . "\n" . implode("\n", $nodes['interface']) . "\n" . implode("\n", $nodes['unknown']) . "\n\n" . implode("\n", $linksDot) . "\n}\n";
        print strlen($dot);
        print $folder . '/' . $name . '.' . self::FILE_EXTENSION;
        file_put_contents($folder . '/' . $name . '.' . self::FILE_EXTENSION, $dot);
    }