0.0
The project is in a healthy, maintained state
A thin, standalone gRPC client for the Ultipa graph database (ultipa-gqldb) - the Ultipa driver behind Tina4's graph layer, usable on its own.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 1.2
 Project Readme

Tina4   ×   Ultipa

tina4-ultipa

The Ultipa graph driver for Ruby

A full-fidelity gRPC client for the Ultipa graph database — every GQL type decoded, no Tina4 lock-in.

RubyGems Tests MIT Ultipa Tina4

Quick Start • Type Support • Ultipa Docs • Protocol • tina4.com


A thin, standalone gRPC driver for the Ultipa graph database (ultipa-gqldb). It is the Ultipa driver behind Tina4's graph data layer — but has no Tina4 dependency and is perfectly usable on its own. Tina4's core stays zero-dependency; this driver is an optional gem loaded only for ultipa:// connections, speaking gRPC directly on top of the pure-Ruby http-2 gem — with no grpc C extension and no google-protobuf runtime. Zero native code, zero transitive deps: bundle install pulls exactly one gem (http-2).

Ultipa is a high-performance graph database with a GQL (ISO/IEC 39075) query surface. Learn more at ultipa.com · docs at ultipa.com/docs.

Why this driver

  • Complete value decoding. Every gqldb PropertyType is decoded to a natural Ruby value — including the composites and temporals most thin clients skip (see Type support).
  • Pure Ruby, zero C extensions. No grpc gem, no google-protobuf, no native compilation on gem install. HTTP/2 runs through the pure-Ruby http-2 gem (lib/tina4_ultipa/grpc.rb layers gRPC framing on top), and the proto3 wire codec is hand-rolled in lib/tina4_ultipa/pb.rb for the 8 gqldb messages we consume. Faster installs, no toolchain, and none of the google-protobuf transitive-pin conflicts that bite in mixed dep graphs.
  • Fails loud. A bad statement raises; it never returns a falsy value you might miss. An unreachable host raises within your connect_timeout.
  • Cross-language parity. The same driver exists for Python, Node.js, Ruby and PHP, decoding byte-for-byte identically.

Install

gem install tina4-ultipa

or in a Gemfile:

gem "tina4-ultipa"

Quick start

require "tina4_ultipa"

# from a URL...
db = Tina4Ultipa::Client.from_url("ultipa://admin:password@localhost:60061/mygraph").connect
# ...or explicitly
db = Tina4Ultipa::Client.new(
  host: "localhost", port: 60061,
  username: "admin", password: "password", graph: "mygraph"
).connect

# read — GQL text + optional named params
db.query("MATCH (n:Person) WHERE n.age > $min RETURN n.name AS name",
         params: { min: 21 }).each do |row|
  puts row["name"]
end

# write — dml stats on success, raises on a bad statement
r = db.execute("INSERT (:Person {name: 'Alice', age: 30})")
puts r.dml_stats[:inserted_nodes]   # 1

db.close

query runs a read, execute a write — both take GQL and optional params and return a Tina4Ultipa::Result:

Member Meaning
#columns column names
#rows decoded rows (arrays of Ruby values)
#to_h_rows / #dicts rows as hashes keyed by column
#scalar first cell of the first row
#rows_affected, #dml_stats, #warnings write metadata

Result is Enumerable and yields each row as a hash, so each, map and select work directly on a result.

Errors: a bad statement raises Tina4Ultipa::Error; an unreachable host raises Tina4Ultipa::ConnectError within connect_timeout, naming host, port and elapsed time.

Type support

Every gqldb PropertyType decodes to a natural Ruby value:

Category Types Decodes to
Numeric int32/uint32/int64/uint64, float, double Integer / Float
Text string, text String
Boolean / null bool, null, unset true/false / nil
Binary blob binary String (e.g. an image, round-trips intact)
Decimal decimal String (precision-preserving)
Temporal date, local/zoned time, local/zoned datetime, timestamp ISO-8601 String
Interval year-to-month, day-to-second {"months" => …} / {"seconds" => …, "nanoseconds" => …}
Spatial point, point3d {"x", "y"[, "z"], "srid"} Hash
Vector vector Array of Float
Graph node, edge, path Hash (_kind node/edge/path; nodes/edges carry id, labels/type, properties, internal uuid)
Tabular list, set, map, record, table Array / Hash
Error error {"code", "message"}

Node/edge hashes include the 8-byte internal-id (uuid) trailer emitted by gqldb 6.1.147+.

Protocol

ultipa-gqldb speaks gRPC (default port 60061, protobuf package gqldb). The driver authenticates with SessionService.Login, passes the returned session_id on every call as the session-id metadata header (as an unsigned decimal), then runs QueryService.Gql. Each value is a TypedValue{type, bytes}; all multi-byte integers are little-endian. The full byte-level encoding is documented in PROTOCOL.md — grounded in Ultipa's official gqldb SDK and proto, and verified live against gqldb-grpc 6.2.130 CE.

Sample data pack

Get a real graph into your community-edition instance in seconds - 10 people (with photos), 3 companies, 3 projects, 5 skills and 62 relationships:

ruby examples/seed.rb ultipa://admin:PASSWORD@HOST:60061
# graph defaults to "default"; override with TINA4_ULTIPA_GRAPH

Then explore it:

MATCH (n:Person)-[e]->(m) RETURN n, e, m LIMIT 100
RETURN db.overview()

The pack lives in examples/ - people.json describes the graph and sample_data/faces/*.jpg are 64px portraits of AI-generated, non-existent people (thispersondoesnotexist.com) stored as BLOB properties, so it also demonstrates binary round-tripping through gqldb. Re-running is safe - it clears the demo labels (Person/Company/Project/Skill) first.

Testing

Real, no-mock tests run against a live server:

TINA4_TEST_ULTIPA_URL=ultipa://admin:password@host:60061 ruby test/test_driver.rb

They cover scalars, node/edge/list/map decoding, the full temporal/spatial/interval set, path decoding, and a BLOB image round-trip.

Links

License

MIT. Note: the Ultipa community-edition server is licensed by Ultipa for personal / non-commercial use — review Ultipa's terms before you deploy it. This driver is an independent client and may not be officially supported by Ultipa.


Sponsored by Code Infinity · part of the Tina4 stack.