rdf-borsh 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +2 -0
- data/README.md +24 -6
- data/VERSION +1 -1
- data/lib/rdf/borsh/reader.rb +15 -12
- data/lib/rdf/borsh/writer.rb +64 -15
- data/lib/rdf/borsh.rb +4 -2
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12224960d664fe3f0b70581cb3c1a0bce77e7425cd0cc9a83b4e6df9fe8d71f7
|
4
|
+
data.tar.gz: d83f64ba1f5e33243dd091b0a04e6c7c39a401bb057703ae03b1373278196204
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cea629b36b4aaea1e18c292210f9942e6ac2ee26659164daffa0540ddbe82fbb8bd54f57c55a726268ce4a985f611ee870fcb6feb31c3fb8b9f92dd914927ed4
|
7
|
+
data.tar.gz: 960ba17587d985344357d9c8c1b12e63827e070cb66ea1f0479727df8578519269d8bbfc24ad6a6925c261037db958b1cd897c64e403813b82f74a7e6350b9d5
|
data/CHANGES.md
CHANGED
@@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## 1.0.2 - 2025-01-11
|
9
|
+
|
8
10
|
## 1.0.1 - 2025-01-07
|
9
11
|
|
10
12
|
## 1.0.0 - 2025-01-07
|
data/README.md
CHANGED
@@ -3,17 +3,25 @@
|
|
3
3
|
[![License](https://img.shields.io/badge/license-Public%20Domain-blue.svg)](https://unlicense.org)
|
4
4
|
[![Compatibility](https://img.shields.io/badge/ruby-3.0%2B-blue)](https://rubygems.org/gems/rdf-borsh)
|
5
5
|
[![Package](https://img.shields.io/gem/v/rdf-borsh)](https://rubygems.org/gems/rdf-borsh)
|
6
|
+
[![Documentation](https://img.shields.io/badge/rubydoc-latest-blue)](https://rubydoc.info/gems/rdf-borsh)
|
6
7
|
|
7
|
-
|
8
|
-
the [Borsh] binary serialization
|
8
|
+
**RDF/Borsh** is a [Ruby] library and [RDF.rb] extension for encoding
|
9
|
+
and decoding [RDF] knowledge graphs in the [Borsh] binary serialization
|
10
|
+
format. (See the [specification].)
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
## ✨ Features
|
13
|
+
|
14
|
+
- Serializes RDF datasets into compact and efficient binary files.
|
15
|
+
- Implements the `application/x-rdf+borsh` MIME type with a `.rdfb` extension.
|
16
|
+
- Employes LZ4 compression for both the term dictionary and quad data.
|
17
|
+
- Designed for blockchain and distributed ledger applications.
|
18
|
+
- Supports reading from and writing to files or I/O streams.
|
19
|
+
- Plays nice with others: entirely contained in the `RDF::Borsh` module.
|
20
|
+
- 100% free and unencumbered public domain software.
|
13
21
|
|
14
22
|
## 🛠️ Prerequisites
|
15
23
|
|
16
|
-
- [Ruby]
|
24
|
+
- [Ruby] 3.0+
|
17
25
|
|
18
26
|
## ⬇️ Installation
|
19
27
|
|
@@ -54,6 +62,10 @@ graph.to_a
|
|
54
62
|
RDF::Borsh::Reader.new($stdin).to_a
|
55
63
|
```
|
56
64
|
|
65
|
+
## 📚 Reference
|
66
|
+
|
67
|
+
https://rubydoc.info/gems/rdf-borsh
|
68
|
+
|
57
69
|
## 👨💻 Development
|
58
70
|
|
59
71
|
```bash
|
@@ -66,3 +78,9 @@ git clone https://github.com/ruby-rdf/rdf-borsh.git
|
|
66
78
|
[![Share on Reddit](https://img.shields.io/badge/share%20on-reddit-red?logo=reddit)](https://reddit.com/submit?url=https://github.com/ruby-rdf/rdf-borsh&title=RDF%2FBorsh+for+Ruby)
|
67
79
|
[![Share on Hacker News](https://img.shields.io/badge/share%20on-hacker%20news-orange?logo=ycombinator)](https://news.ycombinator.com/submitlink?u=https://github.com/ruby-rdf/rdf-borsh&t=RDF%2FBorsh+for+Ruby)
|
68
80
|
[![Share on Facebook](https://img.shields.io/badge/share%20on-facebook-1976D2?logo=facebook)](https://www.facebook.com/sharer/sharer.php?u=https://github.com/ruby-rdf/rdf-borsh)
|
81
|
+
|
82
|
+
[Borsh]: https://borsh.io
|
83
|
+
[RDF]: https://www.w3.org/TR/rdf12-concepts/
|
84
|
+
[RDF.rb]: https://github.com/ruby-rdf/rdf
|
85
|
+
[Ruby]: https://ruby-lang.org
|
86
|
+
[specification]: https://github.com/ruby-rdf/rdf-borsh/blob/master/doc/spec.md
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.2
|
data/lib/rdf/borsh/reader.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# This is free and unencumbered software released into the public domain.
|
2
2
|
|
3
|
+
require 'borsh'
|
3
4
|
require 'extlz4'
|
4
5
|
require 'rdf'
|
5
6
|
require 'stringio'
|
@@ -15,15 +16,17 @@ module RDF::Borsh
|
|
15
16
|
def initialize(input = $stdin, **options, &block)
|
16
17
|
super(input, **options) do
|
17
18
|
input = @input
|
19
|
+
|
20
|
+
@input.extend(Borsh::Readable)
|
18
21
|
@version, @flags, @quad_count = self.read_header
|
19
22
|
|
20
|
-
input_size = input.
|
21
|
-
@input =
|
23
|
+
input_size = input.read_u32
|
24
|
+
@input = Borsh::Buffer.new(self.decompress(input.read(input_size)))
|
22
25
|
@terms = [nil] + self.read_terms
|
23
26
|
|
24
|
-
input_size = input.
|
25
|
-
@input =
|
26
|
-
_ = @input.
|
27
|
+
input_size = input.read_u32
|
28
|
+
@input = Borsh::Buffer.new(self.decompress(input.read(input_size)))
|
29
|
+
_ = @input.read_u32
|
27
30
|
|
28
31
|
if block_given?
|
29
32
|
case block.arity
|
@@ -46,9 +49,9 @@ module RDF::Borsh
|
|
46
49
|
##
|
47
50
|
# Reads the compressed terms dictionary.
|
48
51
|
def read_terms
|
49
|
-
term_count = @input.
|
52
|
+
term_count = @input.read_u32
|
50
53
|
term_count.times.map do
|
51
|
-
term_kind, term_string_size = @input.
|
54
|
+
term_kind, term_string_size = @input.read_u8, @input.read_u32
|
52
55
|
term_string = @input.read(term_string_size)
|
53
56
|
|
54
57
|
case term_kind
|
@@ -56,10 +59,10 @@ module RDF::Borsh
|
|
56
59
|
when 2 then RDF::Node(term_string)
|
57
60
|
when 3 then RDF::Literal(term_string)
|
58
61
|
when 4
|
59
|
-
term_datatype_size = @input.
|
62
|
+
term_datatype_size = @input.read_u32
|
60
63
|
RDF::Literal(term_string, datatype: @input.read(term_datatype_size))
|
61
64
|
when 5
|
62
|
-
term_language_size = @input.
|
65
|
+
term_language_size = @input.read_u32
|
63
66
|
RDF::Literal(term_string, language: @input.read(term_language_size))
|
64
67
|
else
|
65
68
|
raise RDF::ReaderError, "unknown RDF/Borsh term type: #{term_kind}"
|
@@ -73,13 +76,13 @@ module RDF::Borsh
|
|
73
76
|
magic = @input.read(4).unpack('a4').first
|
74
77
|
raise RDF::ReaderError, "invalid RDF/Borsh header: #{magic.inspect}" if magic != MAGIC
|
75
78
|
|
76
|
-
version = @input.
|
79
|
+
version = @input.read_u8
|
77
80
|
raise RDF::ReaderError, "invalid RDF/Borsh version: #{version}" if version != VERSION
|
78
81
|
|
79
|
-
flags = @input.
|
82
|
+
flags = @input.read_u8
|
80
83
|
raise RDF::ReaderError, "invalid RDF/Borsh flags: #{flags}" if flags != FLAGS
|
81
84
|
|
82
|
-
quad_count = @input.
|
85
|
+
quad_count = @input.read_u32
|
83
86
|
[version, flags, quad_count]
|
84
87
|
end
|
85
88
|
|
data/lib/rdf/borsh/writer.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# This is free and unencumbered software released into the public domain.
|
2
2
|
|
3
|
+
require 'borsh'
|
3
4
|
require 'extlz4'
|
4
5
|
require 'rdf'
|
5
6
|
require 'sorted_set'
|
6
|
-
require 'stringio'
|
7
7
|
|
8
8
|
module RDF::Borsh
|
9
9
|
class Writer < RDF::Writer
|
@@ -14,7 +14,19 @@ module RDF::Borsh
|
|
14
14
|
FLAGS = RDF::Borsh::Format::FLAGS
|
15
15
|
LZ4HC_CLEVEL_MAX = 12
|
16
16
|
|
17
|
+
##
|
18
|
+
# Initializes the RDF/Borsh writer.
|
19
|
+
#
|
20
|
+
# @param [IO, StringIO] output
|
21
|
+
# @param [Hash{Symbol => Object}] options
|
22
|
+
# @yield [writer]
|
23
|
+
# @yieldparam [RDF::Borsh::Writer] writer
|
24
|
+
# @yieldreturn [void]
|
25
|
+
# @return [void]
|
17
26
|
def initialize(output = $stdout, **options, &block)
|
27
|
+
output.extend(Borsh::Writable)
|
28
|
+
output.binmode if output.respond_to?(:binmode)
|
29
|
+
|
18
30
|
@terms_dict, @terms_map = [], {}
|
19
31
|
@quads_set = SortedSet.new
|
20
32
|
|
@@ -29,10 +41,25 @@ module RDF::Borsh
|
|
29
41
|
end
|
30
42
|
end
|
31
43
|
|
44
|
+
##
|
45
|
+
# Writes an RDF triple.
|
46
|
+
#
|
47
|
+
# @param [RDF::Resource] subject
|
48
|
+
# @param [RDF::URI] predicate
|
49
|
+
# @param [RDF::Term] object
|
50
|
+
# @return [void]
|
32
51
|
def write_triple(subject, predicate, object)
|
33
52
|
self.write_quad(subject, predicate, object, nil)
|
34
53
|
end
|
35
54
|
|
55
|
+
##
|
56
|
+
# Writes an RDF quad.
|
57
|
+
#
|
58
|
+
# @param [RDF::Resource] subject
|
59
|
+
# @param [RDF::URI] predicate
|
60
|
+
# @param [RDF::Term] object
|
61
|
+
# @param [RDF::Resource] context
|
62
|
+
# @return [void]
|
36
63
|
def write_quad(subject, predicate, object, context)
|
37
64
|
s = self.intern_term(subject)
|
38
65
|
p = self.intern_term(predicate)
|
@@ -41,29 +68,42 @@ module RDF::Borsh
|
|
41
68
|
@quads_set << [g, s, p, o]
|
42
69
|
end
|
43
70
|
|
71
|
+
##
|
72
|
+
# Flushes the output.
|
73
|
+
#
|
74
|
+
# @return [void]
|
44
75
|
def flush
|
45
76
|
self.finish
|
46
77
|
super
|
47
78
|
end
|
48
79
|
|
80
|
+
##
|
81
|
+
# Finishes writing the output.
|
82
|
+
#
|
83
|
+
# @return [void]
|
49
84
|
def finish
|
50
85
|
self.write_header
|
51
86
|
self.write_terms
|
52
87
|
self.write_quads
|
53
88
|
end
|
54
89
|
|
90
|
+
##
|
55
91
|
# Writes the uncompressed header.
|
92
|
+
#
|
93
|
+
# @return [void]
|
56
94
|
def write_header
|
57
95
|
@output.binmode
|
58
96
|
@output.write([MAGIC, VERSION, FLAGS].pack('a4CC'))
|
59
|
-
@output.
|
97
|
+
@output.write_u32(@quads_set.size)
|
60
98
|
end
|
61
99
|
|
100
|
+
##
|
62
101
|
# Writes the compressed terms dictionary.
|
102
|
+
#
|
103
|
+
# @return [void]
|
63
104
|
def write_terms
|
64
|
-
buffer =
|
65
|
-
output.
|
66
|
-
output.write([@terms_dict.size].pack('V'))
|
105
|
+
buffer = self.compress do |output|
|
106
|
+
output.write_u32(@terms_dict.size)
|
67
107
|
@terms_dict.each do |term|
|
68
108
|
output.write(case
|
69
109
|
when term.iri?
|
@@ -87,25 +127,30 @@ module RDF::Borsh
|
|
87
127
|
raise RDF::WriterError, "unsupported RDF/Borsh term type: #{term.inspect}"
|
88
128
|
end)
|
89
129
|
end
|
90
|
-
self.compress(output.string)
|
91
130
|
end
|
92
|
-
@output.
|
131
|
+
@output.write_u32(buffer.size)
|
93
132
|
@output.write(buffer)
|
94
133
|
end
|
95
134
|
|
135
|
+
##
|
136
|
+
# Writes the compressed quads set.
|
137
|
+
#
|
138
|
+
# @return [void]
|
96
139
|
def write_quads
|
97
|
-
buffer =
|
98
|
-
output.
|
99
|
-
output.write([@quads_set.size].pack('V'))
|
140
|
+
buffer = self.compress do |output|
|
141
|
+
output.write_u32(@quads_set.size)
|
100
142
|
@quads_set.each do |quad|
|
101
|
-
output.
|
143
|
+
quad.each { |tid| output.write_u16(tid) }
|
102
144
|
end
|
103
|
-
self.compress(output.string)
|
104
145
|
end
|
105
|
-
@output.
|
146
|
+
@output.write_u32(buffer.size)
|
106
147
|
@output.write(buffer)
|
107
148
|
end
|
108
149
|
|
150
|
+
##
|
151
|
+
# Interns the given RDF term.
|
152
|
+
#
|
153
|
+
# @param [RDF::Term] term
|
109
154
|
# @return [Integer]
|
110
155
|
def intern_term(term)
|
111
156
|
return 0 if term.nil? # for the default graph
|
@@ -118,8 +163,12 @@ module RDF::Borsh
|
|
118
163
|
term_id
|
119
164
|
end
|
120
165
|
|
121
|
-
|
122
|
-
|
166
|
+
##
|
167
|
+
# @yield [Borsh::Buffer]
|
168
|
+
# @return [String]
|
169
|
+
def compress(&block)
|
170
|
+
uncompressed = Borsh::Buffer.open(&block)
|
171
|
+
LZ4::BlockEncoder.new(LZ4HC_CLEVEL_MAX).encode(uncompressed)
|
123
172
|
end
|
124
173
|
end # Writer
|
125
174
|
end # RDF::Borsh
|
data/lib/rdf/borsh.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# This is free and unencumbered software released into the public domain.
|
2
2
|
|
3
|
+
require 'rdf'
|
4
|
+
|
3
5
|
module RDF
|
4
6
|
##
|
5
|
-
# RDF/Borsh.
|
7
|
+
# RDF/Borsh extension for RDF.rb.
|
6
8
|
module Borsh
|
7
9
|
autoload :Format, 'rdf/borsh/format'
|
8
10
|
autoload :Reader, 'rdf/borsh/reader'
|
@@ -10,4 +12,4 @@ module RDF
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
13
|
-
|
15
|
+
require_relative 'borsh/version'
|
metadata
CHANGED
@@ -1,14 +1,28 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdf-borsh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arto Bendiken
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-01-
|
10
|
+
date: 2025-01-11 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: borsh
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0.1'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0.1'
|
12
26
|
- !ruby/object:Gem::Dependency
|
13
27
|
name: extlz4
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,7 +130,7 @@ licenses:
|
|
116
130
|
metadata:
|
117
131
|
bug_tracker_uri: https://github.com/ruby-rdf/rdf-borsh/issues
|
118
132
|
changelog_uri: https://github.com/ruby-rdf/rdf-borsh/blob/master/CHANGES.md
|
119
|
-
documentation_uri: https://
|
133
|
+
documentation_uri: https://rubydoc.info/gems/rdf-borsh
|
120
134
|
homepage_uri: https://github.com/ruby-rdf/rdf-borsh
|
121
135
|
source_code_uri: https://github.com/ruby-rdf/rdf-borsh
|
122
136
|
rdoc_options: []
|