ordlite 0.0.1 → 0.1.1

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: bab34acd6766a0c9219ceb16dc38ca59bf19b33b7de6a54aed644b5680ec5563
4
- data.tar.gz: 62411ce2e9563bb9387a1f1fe72b5bb53f408a644a10f846a6ec4664647282d4
3
+ metadata.gz: 349d70aaa528cdced0835181ca83ad5bb8815982bc60bc7f9d5535095131b322
4
+ data.tar.gz: 505f8f222ea148ca87f84080696cc0ec8d369a1a285aa50270ce8db6632ace96
5
5
  SHA512:
6
- metadata.gz: edad4aa42248de21b75ba2c7a7d3a372fb23c671b1ee38d1f7fcb971a3f3f86afb8f0c532988091f528024cfc8e23b3f46e2c53c1995f2bb910f1de4dada62e3
7
- data.tar.gz: 3a4a42f490533813a585e86e5edc7333462cb92684df9b0b761c2a44a0590dfac8acae49c6fcc630f785fe11bcb18b9ee340e169c90aced3e1d469539048cd21
6
+ metadata.gz: 4a1ecae2ec91d531ae6ff660dea7861243569f7c2009cbf48315e88a406ddbc0b9cdf91a8b29291b8e64e2f99d5051188662356a3bbf70efd394d4f7e7f13cfa
7
+ data.tar.gz: 50cc3f57b2cade5086a12a9c459469a991a667fe9b30431f2b2f6c957c1462430a41bbd6e2e50b635631668d4f6f3ef70aa54a6f6ec7a9d812a17c920b1031f2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,4 @@
1
+ ### 0.1.1 / 2023-07-01
1
2
  ### 0.0.1 / 2023-07-01
2
3
 
3
4
  * Everything is new. First release
data/Manifest.txt CHANGED
@@ -3,3 +3,10 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/ordlite.rb
6
+ lib/ordlite/base.rb
7
+ lib/ordlite/cache.rb
8
+ lib/ordlite/models/blob.rb
9
+ lib/ordlite/models/forward.rb
10
+ lib/ordlite/models/inscribe.rb
11
+ lib/ordlite/schema.rb
12
+ lib/ordlite/version.rb
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
1
  require 'hoe'
2
- ## require './lib/ordlite/version.rb'
2
+ require './lib/ordlite/version.rb'
3
3
 
4
4
  Hoe.spec 'ordlite' do
5
5
 
6
- self.version = '0.0.1' ##Pixelart::Module::Ordgen::VERSION
6
+ self.version = Ordlite::VERSION
7
7
 
8
8
 
9
9
  self.summary = "ordlite - ordinals inscription (on bitcoin & co) database let's you query via sql and more"
@@ -20,6 +20,11 @@ Hoe.spec 'ordlite' do
20
20
 
21
21
  self.extra_deps = [
22
22
  ['activerecord'],
23
+ ['activerecord-utils'],
24
+ ['logutils'],
25
+ ['logutils-activerecord'],
26
+ ['props'],
27
+ ['props-activerecord'],
23
28
  ['sqlite3'],
24
29
  ]
25
30
 
@@ -0,0 +1,106 @@
1
+ # core and stlibs
2
+
3
+ require 'pp'
4
+ require 'fileutils'
5
+ require 'uri'
6
+ require 'json'
7
+ require 'yaml'
8
+
9
+ require 'logger' # Note: use for ActiveRecord::Base.logger -- remove/replace later w/ LogUtils::Logger ???
10
+
11
+
12
+ # 3rd party gems / libs
13
+ require 'props' # see github.com/rubylibs/props
14
+ require 'logutils' # see github.com/rubylibs/logutils
15
+
16
+
17
+ require 'active_record' ## todo: add sqlite3? etc.
18
+
19
+ ## add more activerecords addons/utils
20
+ # require 'tagutils'
21
+ require 'activerecord/utils'
22
+ require 'props/activerecord' # includes ConfDb (ConfDb::Model::Prop, etc.)
23
+ require 'logutils/activerecord' # includes LogDb (LogDb::Model::Log, etc.)
24
+
25
+
26
+
27
+ # our own code
28
+ require_relative 'version' # always goes first
29
+
30
+ require_relative 'models/forward'
31
+
32
+ require_relative 'models/inscribe'
33
+ require_relative 'models/blob'
34
+
35
+
36
+ require_relative 'schema'
37
+
38
+ require_relative 'cache'
39
+
40
+
41
+
42
+ module OrdDb
43
+
44
+ def self.create
45
+ CreateDb.new.up
46
+ ConfDb::Model::Prop.create!( key: 'db.schema.ord.version',
47
+ value: Ordlite::VERSION )
48
+ end
49
+
50
+ def self.create_all
51
+ LogDb.create # add logs table
52
+ ConfDb.create # add props table
53
+ OrdDb.create
54
+ end
55
+
56
+ def self.connect( config={} )
57
+
58
+ if config.empty?
59
+ puts "ENV['DATBASE_URL'] - >#{ENV['DATABASE_URL']}<"
60
+
61
+ ### change default to ./ord.db ?? why? why not?
62
+ db = URI.parse( ENV['DATABASE_URL'] || 'sqlite3:///ord.db' )
63
+
64
+ if db.scheme == 'postgres'
65
+ config = {
66
+ adapter: 'postgresql',
67
+ host: db.host,
68
+ port: db.port,
69
+ username: db.user,
70
+ password: db.password,
71
+ database: db.path[1..-1],
72
+ encoding: 'utf8'
73
+ }
74
+ else # assume sqlite3
75
+ config = {
76
+ adapter: db.scheme, # sqlite3
77
+ database: db.path[1..-1] # ord.db (NB: cut off leading /, thus 1..-1)
78
+ }
79
+ end
80
+ end
81
+
82
+ puts "Connecting to db using settings: "
83
+ pp config
84
+ ActiveRecord::Base.establish_connection( config )
85
+ # ActiveRecord::Base.logger = Logger.new( STDOUT )
86
+ end
87
+
88
+
89
+ def self.setup_in_memory_db
90
+
91
+ # Database Setup & Config
92
+ ActiveRecord::Base.logger = Logger.new( STDOUT )
93
+ ## ActiveRecord::Base.colorize_logging = false - no longer exists - check new api/config setting?
94
+
95
+ self.connect( adapter: 'sqlite3',
96
+ database: ':memory:' )
97
+
98
+ ## build schema
99
+ OrdDb.create_all
100
+ end # setup_in_memory_db (using SQLite :memory:)
101
+
102
+ end # module OrdDb
103
+
104
+
105
+ # say hello
106
+ puts Ordlite.banner ## if defined?($RUBYCOCOS_DEBUG) && $RUBCOCOS_DEBUG
@@ -0,0 +1,123 @@
1
+
2
+ module OrdDb
3
+
4
+
5
+ class Cache
6
+
7
+ Inscribe = Model::Inscribe
8
+ Blob = Model::Blob
9
+
10
+ def initialize( dir='.' )
11
+ @dir = dir
12
+ end
13
+
14
+
15
+
16
+ def import_all
17
+ paths = Dir.glob( "#{@dir}/**.json" )
18
+ puts " #{paths.size} inscribe datafile(s) found"
19
+
20
+ paths.each_with_index do |path, i|
21
+ puts "==> inscribe #{i+1}/#{paths.size}..."
22
+ data = _read_inscribe( path )
23
+
24
+ Inscribe.create( _parse_inscribe( data ))
25
+ end
26
+
27
+
28
+ paths = Dir.glob( "#{@dir}/content/**.txt" )
29
+ puts " #{paths.size} content datafile(s) found"
30
+
31
+ paths.each_with_index do |path, i|
32
+ puts "==> blob #{i+1}/#{paths.size}..."
33
+ content = _read_blob( path )
34
+ id = File.basename( path, File.extname( path ))
35
+
36
+ Blob.create( id: id,
37
+ content: content )
38
+ end
39
+ end
40
+
41
+
42
+ def import( id )
43
+ data = read( id )
44
+ rec = Inscribe.create( _parse_inscribe( data ))
45
+ rec
46
+ end
47
+
48
+ def read( id )
49
+ _read_inscribe( "#{@dir}/#{id}.json" )
50
+ end
51
+
52
+ def _read_inscribe( path )
53
+ JSON.parse( _read_text( path ))
54
+ end
55
+
56
+ def _read_blob( path )
57
+ blob = File.open( path, 'rb' ) { |f| f.read }
58
+ ## auto force to ASCII-7BIT if not already - why? why not?
59
+ blob
60
+ end
61
+
62
+
63
+ def _read_text( path )
64
+ File.open( path, 'r:utf-8' ){ |f| f.read }
65
+ end
66
+
67
+ def _parse_inscribe( data )
68
+ ## num via title
69
+ attributes = {
70
+ id: data['id'],
71
+ num: _title_to_num( data['title'] ),
72
+ bytes: _content_length_to_bytes( data['content length'] ),
73
+ sat: data['sat'].to_i(10),
74
+ content_type: data['content type'],
75
+ block: data['genesis height'].to_i(10),
76
+ fee: data['genesis fee'].to_i(10),
77
+ tx: data['genesis transaction'],
78
+ address: data['address'],
79
+ output: data['output'],
80
+ value: data['output value'].to_i(10),
81
+ offset: data['offset'].to_i(10),
82
+ # "2023-06-01 05:00:57 UTC"
83
+ date: DateTime.strptime( data['timestamp'],
84
+ '%Y-%m-%d %H:%M:%S %z')
85
+ }
86
+
87
+ attributes
88
+ end
89
+
90
+
91
+
92
+ ## "title": "Inscription 9992615",
93
+ TITLE_RX = /^Inscription (?<num>[0-9]+)$/i
94
+
95
+ def _title_to_num( str )
96
+ if m=TITLE_RX.match( str )
97
+ m[:num].to_i(10) ## use base 10
98
+ else
99
+ puts "!! ERROR - no inscribe num found in title >#{str}<"
100
+ exit 1 ## not found - raise exception - why? why not?
101
+ end
102
+ end
103
+
104
+ CONTENT_LENGTH_RX = /^(?<num>[0-9]+) bytes$/i
105
+
106
+ def _content_length_to_bytes( str )
107
+ if m=CONTENT_LENGTH_RX.match( str )
108
+ m[:num].to_i(10) ## use base 10
109
+ else
110
+ puts "!! ERROR - bytes found in content lenght >#{str}<"
111
+ exit 1 ## not found - raise exception - why? why not?
112
+ end
113
+ end
114
+
115
+
116
+
117
+
118
+ end # class Cache
119
+ end # module OrdDb
120
+
121
+
122
+
123
+
@@ -0,0 +1,11 @@
1
+
2
+ module OrdDb
3
+ module Model
4
+
5
+ class Blob < ActiveRecord::Base
6
+ belongs_to :inscribe, foreign_key: 'id'
7
+ end # class Blob
8
+
9
+ end # module Model
10
+ end # module OrdDb
11
+
@@ -0,0 +1,23 @@
1
+
2
+ ### forward references
3
+ ## require first to resolve circular references
4
+
5
+ module OrdDb
6
+ module Model
7
+
8
+ #############
9
+ # ConfDb
10
+ Prop = ConfDb::Model::Prop
11
+
12
+
13
+ class Inscribe < ActiveRecord::Base ; end
14
+ class Blob < ActiveRecord::Base ; end
15
+
16
+ end
17
+
18
+ # note: convenience alias for Model
19
+ # lets you use include OrdDb::Models
20
+ Models = Model
21
+ end # module # OrdDb
22
+
23
+
@@ -0,0 +1,11 @@
1
+
2
+ module OrdDb
3
+ module Model
4
+
5
+ class Inscribe < ActiveRecord::Base
6
+ has_one :blob, foreign_key: 'id'
7
+ end # class Inscribe
8
+
9
+ end # module Model
10
+ end # module OrdDb
11
+
@@ -0,0 +1,112 @@
1
+
2
+
3
+ module OrdDb
4
+
5
+ class CreateDb
6
+
7
+ def up
8
+
9
+ ActiveRecord::Schema.define do
10
+
11
+
12
+ =begin
13
+ CREATE TABLE inscribes(
14
+ id varchar NOT NULL PRIMARY KEY,
15
+ num integer NOT NULL,
16
+ content_length integer NOT NULL,
17
+ content_type varchar NOT NULL,
18
+ date datetime(6) NOT NULL,
19
+ sat integer NOT NULL,
20
+ height integer NOT NULL,
21
+ fee integer NOT NULL,
22
+ tx varchar NOT NULL,
23
+ offset integer NOT NULL,
24
+ address varchar NOT NULL,
25
+
26
+ created_at datetime(6) NOT NULL,
27
+ updated_at datetime(6) NOT NULL)
28
+
29
+ CREATE TABLE blobs(
30
+ id varchar NOT NULL PRIMARY KEY,
31
+ content blob NOT NULL
32
+
33
+ created_at datetime(6) NOT NULL,
34
+ updated_at datetime(6) NOT NULL)
35
+ =end
36
+
37
+
38
+
39
+ create_table :inscribes, :id => :string do |t|
40
+ ## "id": "0a3a4dbf6630338bc4df8e36bd081f8f7d2dee9441131cb03a18d43eb4882d5ci0",
41
+ ## note: change to uuid (universally unique id) - why? why not?
42
+ ## id gets used by row_id (internal orm db machinery) and is int
43
+ ## t.string :uuid, null: false, index: { unique: true, name: 'inscribe_uuids' }
44
+
45
+ ## "title": "Inscription 10371414",
46
+ ## note: use num/no. from title only - why? why not?
47
+ t.integer :num, null: false, index: { unique: true, name: 'inscribe_nums' }
48
+
49
+ ## "content length": "85 bytes",
50
+ ## note: extract bytes as integer!!!
51
+ ## change to bytes - why? why not?
52
+ t.integer :bytes, null: false
53
+ ## "content type": "text/plain;charset=utf-8",
54
+ ## note: make sure always lower/down case!!!
55
+ t.string :content_type, null: false
56
+
57
+ ## "timestamp": "2023-06-01 05:00:57 UTC"
58
+ ## or use date_utc ???
59
+ t.datetime :date, null: false
60
+
61
+ ##
62
+ ## "sat": "967502783701719",
63
+ t.integer :sat, null: false
64
+
65
+ ##
66
+ ## "genesis height": "792337",
67
+ ## -> change height to block - why? why not?
68
+ ## "genesis fee": "6118",
69
+ ## "genesis transaction": "0a3a4dbf6630338bc4df8e36bd081f8f7d2dee9441131cb03a18d43eb4882d5c",
70
+ ## "offset": "0"
71
+ t.integer :block, null: false
72
+ t.integer :fee, null: false
73
+ t.string :tx, null: false
74
+ t.integer :offset, null: false
75
+
76
+ ###
77
+ ## "address": "bc1p3h4eecuxjj2g72sq38gyva732866u5w29lhxgeqfe6c0sg8xmagsuau63k",
78
+ ## is this minter/inscriber addr???
79
+ t.string :address, null: false
80
+
81
+ ## "output": "0a3a4dbf6630338bc4df8e36bd081f8f7d2dee9441131cb03a18d43eb4882d5c:0",
82
+ ## "output value": "546",
83
+ t.string :output, null: false
84
+ t.integer :value, null: false
85
+
86
+ ## -- ignore for now - why? why not?
87
+ ## what is location ???
88
+ ## "location": "0a3a4dbf6630338bc4df8e36bd081f8f7d2dee9441131cb03a18d43eb4882d5c:0:0",
89
+
90
+ ## timestamp at last
91
+ t.timestamps
92
+ end
93
+
94
+
95
+ create_table :blobs, :id => :string do |t|
96
+ ## "id": "0a3a4dbf6630338bc4df8e36bd081f8f7d2dee9441131cb03a18d43eb4882d5ci0",
97
+ ## note: change to uuid (universally unique id) - why? why not?
98
+ ## id gets used by row_id (internal orm db machinery) and is int
99
+ ## t.string :id, null: false, index: { unique: true, name: 'blob_uuids' }
100
+
101
+ t.binary :content, null: false
102
+
103
+ ## timestamp at last
104
+ t.timestamps
105
+ end
106
+
107
+
108
+ end # block Schema.define
109
+
110
+ end # method up
111
+ end # class CreateDb
112
+ end # module OrdDb
@@ -0,0 +1,22 @@
1
+
2
+ module Ordlite
3
+
4
+ # sync version w/ sport.db n friends - why? why not?
5
+ MAJOR = 0 ## todo: namespace inside version or something - why? why not??
6
+ MINOR = 1
7
+ PATCH = 1
8
+ VERSION = [MAJOR,MINOR,PATCH].join('.')
9
+
10
+ def self.version
11
+ VERSION
12
+ end
13
+
14
+ def self.banner
15
+ "ordlite/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in >#{root}<"
16
+ end
17
+
18
+ def self.root
19
+ File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
20
+ end
21
+
22
+ end
data/lib/ordlite.rb CHANGED
@@ -1,3 +1,12 @@
1
1
 
2
- puts "hello, ordlite!"
2
+ require_relative 'ordlite/base'
3
+
4
+
5
+ ## add convenience helpers
6
+ ## use require 'ordlite/base' if you do NOT want automagic aliases
7
+
8
+
9
+ Inscribe = OrdDb::Model::Inscribe
10
+ Blob = OrdDb::Model::Blob
11
+
3
12
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ordlite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
@@ -24,6 +24,76 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord-utils
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: logutils
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: logutils-activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: props
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: props-activerecord
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
27
97
  - !ruby/object:Gem::Dependency
28
98
  name: sqlite3
29
99
  requirement: !ruby/object:Gem::Requirement
@@ -87,6 +157,13 @@ files:
87
157
  - README.md
88
158
  - Rakefile
89
159
  - lib/ordlite.rb
160
+ - lib/ordlite/base.rb
161
+ - lib/ordlite/cache.rb
162
+ - lib/ordlite/models/blob.rb
163
+ - lib/ordlite/models/forward.rb
164
+ - lib/ordlite/models/inscribe.rb
165
+ - lib/ordlite/schema.rb
166
+ - lib/ordlite/version.rb
90
167
  homepage: https://github.com/ordbase/generative-orc-721
91
168
  licenses:
92
169
  - Public Domain