rsnowflake 0.1.0-x86_64-linux

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 878d11a728ddcba4c4ce661e2312475a8353c6c569b9fdf38877b547d1e36c7f
4
+ data.tar.gz: 5ad63eca57a81e6aeb607f38a60319eed9efcac55e1c0e4990d658587097490f
5
+ SHA512:
6
+ metadata.gz: 996a6eaea7d446d73913a4dfc2712010234c671490d99fd65098d2e368ee12527c0878e7fab003d3bdf1e63f631f47346d50b5177dc0d62475f7c195f184ac39
7
+ data.tar.gz: b8718f821bdabe7f8bac46bd309c55c952ebc919cc061af86b21b4b943d3c1fa7651d87c823a063992eeb5790cebfaf807418e0b209849ea997568e986327f85
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Luiz Eduardo Kowalski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # Rsnowflake
2
+
3
+ Fast Snowflake ID generator with a Rust backend. Thread-safe and highly performant.
4
+
5
+ ## Installation
6
+
7
+ Add to your Gemfile:
8
+
9
+ ```ruby
10
+ gem "rsnowflake"
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ### Basic
16
+
17
+ ```ruby
18
+ require "rsnowflake"
19
+
20
+ id = Rsnowflake.id
21
+ # => 7193489234823847936
22
+ ```
23
+
24
+ ### Configuration
25
+
26
+ ```ruby
27
+ Rsnowflake.configure do |config|
28
+ config.machine_id = 42 # Default: Process.pid % 1024
29
+ config.epoch = Time.utc(2024, 1, 1) # Default: Unix epoch
30
+ end
31
+ ```
32
+
33
+ ### Parsing IDs
34
+
35
+ ```ruby
36
+ id = Rsnowflake.id
37
+
38
+ Rsnowflake.parse(id)
39
+ # => {timestamp_ms: 1735123456789, machine_id: 42, sequence: 0}
40
+
41
+ Rsnowflake.timestamp(id)
42
+ # => 2024-12-25 12:34:56 +0000
43
+
44
+ Rsnowflake.timestamp_ms(id)
45
+ # => 1735123456789
46
+
47
+ Rsnowflake.machine_id(id)
48
+ # => 42
49
+
50
+ Rsnowflake.sequence(id)
51
+ # => 0
52
+ ```
53
+
54
+ ## Requirements
55
+
56
+ - Ruby >= 3.2
57
+ - Rust toolchain (for compilation)
58
+
59
+ ## Development
60
+
61
+ ```bash
62
+ bundle install
63
+ bundle exec rake compile
64
+ bundle exec ruby test/test_rsnowflake.rb
65
+ ```
66
+
67
+ ## License
68
+
69
+ MIT
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rsnowflake
4
+ module AdapterExtension
5
+ SNOWFLAKE_TYPE = { name: "bigint" }.freeze
6
+
7
+ def native_database_types
8
+ super.merge(snowflake: SNOWFLAKE_TYPE)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rsnowflake
4
+ module ModelExtensions
5
+ extend ActiveSupport::Concern
6
+
7
+ class_methods do
8
+ def snowflake_id(*attributes)
9
+ attributes = [:id] if attributes.empty?
10
+
11
+ class_attribute :_snowflake_attributes, instance_writer: false, default: []
12
+ self._snowflake_attributes = _snowflake_attributes | attributes.map(&:to_sym)
13
+
14
+ before_validation :_generate_snowflake_ids, on: :create
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def _generate_snowflake_ids
21
+ self.class._snowflake_attributes.each do |attribute|
22
+ next if self[attribute].present?
23
+
24
+ self[attribute] = Rsnowflake.id
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/railtie"
4
+
5
+ module Rsnowflake
6
+ class Railtie < Rails::Railtie
7
+ initializer "rsnowflake.register_type", after: "active_record.initialize_database" do
8
+ ActiveSupport.on_load(:active_record) do
9
+ require "rsnowflake/type/snowflake"
10
+ ActiveRecord::Type.register(:snowflake, Rsnowflake::Type::Snowflake)
11
+ end
12
+ end
13
+
14
+ initializer "rsnowflake.extend_adapters", after: "active_record.initialize_database" do
15
+ ActiveSupport.on_load(:active_record) do
16
+ require "rsnowflake/adapter_extension"
17
+
18
+ adapters = %w[
19
+ PostgreSQLAdapter
20
+ Mysql2Adapter
21
+ TrilogyAdapter
22
+ SQLite3Adapter
23
+ ]
24
+
25
+ adapters.each do |adapter_name|
26
+ next unless ActiveRecord::ConnectionAdapters.const_defined?(adapter_name)
27
+
28
+ adapter = ActiveRecord::ConnectionAdapters.const_get(adapter_name)
29
+ adapter.prepend(Rsnowflake::AdapterExtension)
30
+ end
31
+ end
32
+ end
33
+
34
+ initializer "rsnowflake.schema_definitions", after: "active_record.initialize_database" do
35
+ ActiveSupport.on_load(:active_record) do
36
+ require "rsnowflake/schema_definitions"
37
+
38
+ ActiveRecord::ConnectionAdapters::TableDefinition.include(Rsnowflake::SchemaDefinitions::TableDefinition)
39
+ ActiveRecord::ConnectionAdapters::Table.include(Rsnowflake::SchemaDefinitions::Table)
40
+ end
41
+ end
42
+
43
+ initializer "rsnowflake.model_extensions", after: "active_record.initialize_database" do
44
+ ActiveSupport.on_load(:active_record) do
45
+ require "rsnowflake/model_extensions"
46
+ ActiveRecord::Base.include(Rsnowflake::ModelExtensions)
47
+ end
48
+ end
49
+ end
50
+ end
Binary file
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rsnowflake
4
+ module SchemaDefinitions
5
+ module TableDefinition
6
+ def snowflake(name, **options)
7
+ column(name, :snowflake, **options)
8
+ end
9
+ end
10
+
11
+ module Table
12
+ def snowflake(name, **options)
13
+ column(name, :snowflake, **options)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rsnowflake
4
+ module Type
5
+ class Snowflake < ActiveRecord::Type::BigInteger
6
+ def type
7
+ :snowflake
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rsnowflake
4
+ VERSION = "0.1.0"
5
+ end
data/lib/rsnowflake.rb ADDED
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rsnowflake/version"
4
+ require_relative "rsnowflake/rsnowflake"
5
+
6
+ require_relative "rsnowflake/railtie" if defined?(Rails::Railtie)
7
+
8
+ module Rsnowflake
9
+ MAX_MACHINE_ID = 1023
10
+
11
+ class Error < StandardError; end
12
+ class ConfigurationError < Error; end
13
+
14
+ class Configuration
15
+ attr_accessor :machine_id, :epoch
16
+
17
+ def initialize
18
+ @machine_id = nil
19
+ @epoch = nil
20
+ end
21
+
22
+ def machine_id_value
23
+ id = @machine_id || default_machine_id
24
+ id % (MAX_MACHINE_ID + 1)
25
+ end
26
+
27
+ def epoch_ms
28
+ return nil unless @epoch
29
+
30
+ (@epoch.to_f * 1000).to_i
31
+ end
32
+
33
+ private
34
+
35
+ def default_machine_id
36
+ Process.pid % (MAX_MACHINE_ID + 1)
37
+ end
38
+ end
39
+
40
+ class << self
41
+ def configuration
42
+ @configuration ||= Configuration.new
43
+ end
44
+
45
+ def configure
46
+ yield(configuration) if block_given?
47
+ ensure_initialized!
48
+ configuration
49
+ end
50
+
51
+ def id
52
+ ensure_initialized!
53
+ Internal.generate
54
+ end
55
+
56
+ def parse(id)
57
+ ensure_initialized!
58
+ Internal.parse(id)
59
+ end
60
+
61
+ def timestamp(id)
62
+ time_ms = Internal.timestamp_ms(id)
63
+ Time.at(time_ms / 1000, (time_ms % 1000) * 1000, :usec)
64
+ end
65
+
66
+ def timestamp_ms(id)
67
+ Internal.timestamp_ms(id)
68
+ end
69
+
70
+ def machine_id(id)
71
+ Internal.machine_id(id)
72
+ end
73
+
74
+ def sequence(id)
75
+ Internal.sequence(id)
76
+ end
77
+
78
+ def reset!
79
+ raise ConfigurationError, "Cannot reset after initialization" if Internal.initialized?
80
+
81
+ @configuration = Configuration.new
82
+ end
83
+
84
+ private
85
+
86
+ def ensure_initialized!
87
+ return if Internal.initialized?
88
+
89
+ config = configuration
90
+ Internal.init_generator(config.machine_id_value, config.epoch_ms)
91
+ end
92
+ end
93
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rsnowflake
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: x86_64-linux
6
+ authors:
7
+ - Luiz Eduardo Kowalski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-01-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A Ruby gem for generating Twitter Snowflake IDs using a high-performance
14
+ Rust backend. Thread-safe with configurable machine ID and custom epoch support.
15
+ email:
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE.txt
21
+ - README.md
22
+ - lib/rsnowflake.rb
23
+ - lib/rsnowflake/3.2/rsnowflake.so
24
+ - lib/rsnowflake/3.3/rsnowflake.so
25
+ - lib/rsnowflake/3.4/rsnowflake.so
26
+ - lib/rsnowflake/4.0/rsnowflake.so
27
+ - lib/rsnowflake/adapter_extension.rb
28
+ - lib/rsnowflake/model_extensions.rb
29
+ - lib/rsnowflake/railtie.rb
30
+ - lib/rsnowflake/rsnowflake.bundle
31
+ - lib/rsnowflake/schema_definitions.rb
32
+ - lib/rsnowflake/type/snowflake.rb
33
+ - lib/rsnowflake/version.rb
34
+ homepage: https://github.com/luizkowalski/rsnowflake
35
+ licenses:
36
+ - MIT
37
+ metadata:
38
+ homepage_uri: https://github.com/luizkowalski/rsnowflake
39
+ source_code_uri: https://github.com/luizkowalski/rsnowflake
40
+ changelog_uri: https://github.com/luizkowalski/rsnowflake/blob/main/CHANGELOG.md
41
+ bug_tracker_uri: https://github.com/luizkowalski/rsnowflake/issues
42
+ rubygems_mfa_required: 'true'
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '3.2'
52
+ - - "<"
53
+ - !ruby/object:Gem::Version
54
+ version: 4.1.dev
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubygems_version: 3.5.23
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: Fast Snowflake ID generator with Rust backend
65
+ test_files: []