github.com/cayleygraph/cayley@v0.7.7/query/mql/query.go (about)

     1  // Copyright 2014 The Cayley Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package mql
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/cayleygraph/cayley/graph"
    22  )
    23  
    24  type (
    25  	Path       string
    26  	ResultPath string
    27  )
    28  
    29  type Query struct {
    30  	ses            *Session
    31  	it             graph.Iterator
    32  	isRepeated     map[Path]bool
    33  	queryStructure map[Path]map[string]interface{}
    34  	queryResult    map[ResultPath]map[string]interface{}
    35  	results        []interface{}
    36  	resultOrder    []string
    37  	err            error
    38  }
    39  
    40  func (q *Query) isError() bool {
    41  	return q.err != nil
    42  }
    43  
    44  func (q *Query) copyPathStructure(path Path) map[string]interface{} {
    45  	output := make(map[string]interface{})
    46  	for k, v := range q.queryStructure[path] {
    47  		output[k] = v
    48  	}
    49  	return output
    50  }
    51  
    52  func NewPath() Path {
    53  	return ""
    54  }
    55  func (p Path) Follow(s string) Path {
    56  	return Path(fmt.Sprintf("%s\x1E%s", p, s))
    57  }
    58  
    59  func (p Path) DisplayString() string {
    60  	return strings.Replace(string(p), "\x1E", ".", -1)
    61  }
    62  
    63  func NewResultPath() ResultPath {
    64  	return ""
    65  }
    66  
    67  func (p ResultPath) FollowPath(followPiece string, value string) ResultPath {
    68  	if string(p) == "" {
    69  		return ResultPath(fmt.Sprintf("%s\x1E%s", value, followPiece))
    70  	}
    71  	return ResultPath(fmt.Sprintf("%s\x1E%s\x1E%s", p, value, followPiece))
    72  }
    73  
    74  func (p ResultPath) getPath() Path {
    75  	out := NewPath()
    76  	pathPieces := strings.Split(string(p), "\x1E")
    77  	for len(pathPieces) > 1 {
    78  		a := pathPieces[1]
    79  		pathPieces = pathPieces[2:]
    80  		out = out.Follow(a)
    81  	}
    82  	return out
    83  }
    84  
    85  func (p ResultPath) splitLastPath() (ResultPath, string) {
    86  	pathPieces := strings.Split(string(p), "\x1E")
    87  	return ResultPath(strings.Join(pathPieces[:len(pathPieces)-1], "\x1E")), pathPieces[len(pathPieces)-1]
    88  }
    89  
    90  func (p ResultPath) AppendValue(value string) ResultPath {
    91  	if string(p) == "" {
    92  		return ResultPath(value)
    93  	}
    94  	return ResultPath(fmt.Sprintf("%s\x1E%s", p, value))
    95  }
    96  
    97  func (p Path) ToResultPathFromMap(resultMap map[Path]string) ResultPath {
    98  	output := NewResultPath()
    99  	pathPieces := strings.Split(string(p), "\x1E")[1:]
   100  	pathSoFar := NewPath()
   101  	for _, piece := range pathPieces {
   102  		output = output.FollowPath(piece, resultMap[pathSoFar])
   103  		pathSoFar = pathSoFar.Follow(piece)
   104  	}
   105  	return output
   106  }
   107  
   108  func NewQuery(ses *Session) *Query {
   109  	var q Query
   110  	q.ses = ses
   111  	q.err = nil
   112  	return &q
   113  }