rdf-borsh 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35de9225111f9f281e91c1a287470859366dfe8fce5d211416e8e0a4216cf42a
4
- data.tar.gz: 01f1d2ecd33f0f016c021fb4d24de4ca1333beb739c27b3f1de2f8eff15f579e
3
+ metadata.gz: 12224960d664fe3f0b70581cb3c1a0bce77e7425cd0cc9a83b4e6df9fe8d71f7
4
+ data.tar.gz: d83f64ba1f5e33243dd091b0a04e6c7c39a401bb057703ae03b1373278196204
5
5
  SHA512:
6
- metadata.gz: 8b3442aaf6fffe3abd8de243ca3f3af85fd3ae4b288997344d8051f43198d5601475539e63eea3a62c424b3075ce17dbf3a15f7092883a5909bb3f0c2a7187b5
7
- data.tar.gz: bf2e5f7860fa8f733112713993ccb743b67960f732a7cfc0c4caada867b653d6d8b355d154a91649892459305c8177fe8c8eb6b4ae48f35684e652b1bb2baa0f
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
- An [RDF.rb] extension for encoding and decoding [RDF] knowledge graphs in
8
- the [Borsh] binary serialization format.
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
- [Borsh]: https://borsh.io
11
- [RDF]: https://www.w3.org/TR/rdf12-concepts/
12
- [RDF.rb]: https://github.com/ruby-rdf/rdf
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](https://ruby-lang.org) 3.0+
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
+ 1.0.2
@@ -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.read(4).unpack('V').first
21
- @input = StringIO.new(self.decompress(input.read(input_size)), 'rb')
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.read(4).unpack('V').first
25
- @input = StringIO.new(self.decompress(input.read(input_size)), 'rb')
26
- _ = @input.read(4).unpack('V').first
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.read(4).unpack('V').first
52
+ term_count = @input.read_u32
50
53
  term_count.times.map do
51
- term_kind, term_string_size = @input.read(5).unpack('CV')
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.read(4).unpack('V')
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.read(4).unpack('V')
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.read(1).unpack('C').first
79
+ version = @input.read_u8
77
80
  raise RDF::ReaderError, "invalid RDF/Borsh version: #{version}" if version != VERSION
78
81
 
79
- flags = @input.read(1).unpack('C').first
82
+ flags = @input.read_u8
80
83
  raise RDF::ReaderError, "invalid RDF/Borsh flags: #{flags}" if flags != FLAGS
81
84
 
82
- quad_count = @input.read(4).unpack('V').first
85
+ quad_count = @input.read_u32
83
86
  [version, flags, quad_count]
84
87
  end
85
88
 
@@ -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.write([@quads_set.size].pack('V'))
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 = StringIO.open do |output|
65
- output.binmode
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.write([buffer.size].pack('V'))
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 = StringIO.open do |output|
98
- output.binmode
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.write(quad.pack('v4'))
143
+ quad.each { |tid| output.write_u16(tid) }
102
144
  end
103
- self.compress(output.string)
104
145
  end
105
- @output.write([buffer.size].pack('V'))
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
- def compress(data)
122
- LZ4::BlockEncoder.new(LZ4HC_CLEVEL_MAX).encode(data)
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
- require 'rdf/borsh/version'
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.1
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-07 00:00:00.000000000 Z
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://github.com/ruby-rdf/rdf-borsh/blob/master/README.md
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: []