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 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: []