Class: Tina4Ultipa::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/tina4_ultipa/client.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host:, port: DEFAULT_PORT, username: nil, password: nil, graph: nil, connect_timeout: 10, use_tls: false) ⇒ Client

Returns a new instance of Client.



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/tina4_ultipa/client.rb', line 72

def initialize(host:, port: DEFAULT_PORT, username: nil, password: nil,
               graph: nil, connect_timeout: 10, use_tls: false)
  @host = host
  @port = port.to_i
  @username = username
  @password = password
  @graph = graph || ""
  @connect_timeout = connect_timeout.to_f
  @use_tls = use_tls
  @channel = nil
  @session_id = nil
  @server_version = nil
end

Instance Attribute Details

#connect_timeoutObject (readonly)

Returns the value of attribute connect_timeout.



68
69
70
# File 'lib/tina4_ultipa/client.rb', line 68

def connect_timeout
  @connect_timeout
end

#graphObject

Returns the value of attribute graph.



68
69
70
# File 'lib/tina4_ultipa/client.rb', line 68

def graph
  @graph
end

#hostObject (readonly)

Returns the value of attribute host.



68
69
70
# File 'lib/tina4_ultipa/client.rb', line 68

def host
  @host
end

#portObject (readonly)

Returns the value of attribute port.



68
69
70
# File 'lib/tina4_ultipa/client.rb', line 68

def port
  @port
end

#server_versionObject (readonly)

Returns the value of attribute server_version.



68
69
70
# File 'lib/tina4_ultipa/client.rb', line 68

def server_version
  @server_version
end

#use_tlsObject (readonly)

Returns the value of attribute use_tls.



68
69
70
# File 'lib/tina4_ultipa/client.rb', line 68

def use_tls
  @use_tls
end

#usernameObject (readonly)

Returns the value of attribute username.



68
69
70
# File 'lib/tina4_ultipa/client.rb', line 68

def username
  @username
end

Class Method Details

.from_url(url, **kw) ⇒ Object

ultipa://user:pass@host:port/graph?connect_timeout=5&tls=1



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/tina4_ultipa/client.rb', line 87

def self.from_url(url, **kw)
  u = URI.parse(url)
  q = URI.decode_www_form(u.query || "").to_h
  path_graph = (u.path || "").sub(%r{\A/}, "")
  new(
    host: u.host,
    port: (u.port || DEFAULT_PORT),
    username: (u.user || q["user"] || kw[:username]),
    password: (u.password || q["password"] || kw[:password]),
    graph: (path_graph.empty? ? kw[:graph] : path_graph),
    connect_timeout: (q["connect_timeout"] || kw[:connect_timeout] || 10).to_f,
    use_tls: (%w[1 true].include?(q["tls"]) || url.start_with?("ultipas://") ||
              kw[:use_tls] || false),
  )
end

Instance Method Details

#closeObject



177
178
179
180
181
182
183
184
# File 'lib/tina4_ultipa/client.rb', line 177

def close
  @channel&.close
rescue StandardError
  # best effort - the channel is being torn down regardless
ensure
  @channel = nil
  @session_id = nil
end

#connectObject

-- connection ---------------------------------------------------------



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/tina4_ultipa/client.rb', line 104

def connect
  return self unless @session_id.nil?

  @channel = GrpcClient::Channel.new(
    @host, @port, use_tls: @use_tls, connect_timeout: @connect_timeout,
  )
  started = monotonic
  begin
    @channel.connect
  rescue GrpcClient::ConnectTimeout => e
    elapsed = monotonic - started
    close
    raise ConnectError.new(@host, @port, elapsed, cause: e)
  end

  req = Gqldb::LoginRequest.new(
    username: @username || "", password: @password || "",
    default_graph: @graph,
  )
  begin
    resp_bytes = @channel.unary(
      "/gqldb.SessionService/Login",
      Gqldb::LoginRequest.encode(req),
      timeout: @connect_timeout,
    )
  rescue GrpcClient::RpcError => e
    close
    raise wrap(e, "login failed")
  rescue GrpcClient::ConnectTimeout => e
    elapsed = monotonic - started
    close
    raise ConnectError.new(@host, @port, elapsed, cause: e)
  end

  resp = Gqldb::LoginResponse.decode(resp_bytes)
  @session_id = resp.session_id
  @server_version = resp.server_version
  self
end

#execute(gql, params: nil, graph: nil, timeout: nil) ⇒ Object

Run a writing GQL statement (read_only = false).



173
174
175
# File 'lib/tina4_ultipa/client.rb', line 173

def execute(gql, params: nil, graph: nil, timeout: nil)
  query(gql, params: params, graph: graph, read_only: false, timeout: timeout)
end

#query(gql, params: nil, graph: nil, read_only: true, timeout: nil) ⇒ Object

Run a GQL statement and return a Result. Raises on error.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/tina4_ultipa/client.rb', line 147

def query(gql, params: nil, graph: nil, read_only: true, timeout: nil)
  connect
  req = Gqldb::GqlRequest.new(
    gql: gql,
    graph_name: graph.nil? ? @graph : graph,
    parameters: (params || {}).map do |k, v|
      Gqldb::Parameter.new(name: k.to_s, value: Codec.encode(v))
    end,
    session_id: @session_id || 0,
    read_only: read_only,
    timeout: timeout ? timeout.to_i : 0,
  )
  begin
    resp_bytes = @channel.unary(
      "/gqldb.QueryService/Gql",
      Gqldb::GqlRequest.encode(req),
      metadata: { "session-id" => @session_id.to_s },
      timeout: timeout ? timeout.to_f : nil,
    )
  rescue GrpcClient::RpcError => e
    raise wrap(e, "gql failed")
  end
  Result.new(Gqldb::GqlResponse.decode(resp_bytes))
end