pglite 0.0.4-arm64-darwin

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: d4f783b07d76b4e3e3dbb58b102daaaed3c0ab19ee10f1c204fb66561d99eb2c
4
+ data.tar.gz: 0adc1e0b0010f247d767b45ff9af38ccb5c9aea97a7b078e38490cb98e533ae8
5
+ SHA512:
6
+ metadata.gz: 93abc5fefb9aaffc363e76884db7b2b5dc980e7bb9bfc1161215f3734c57be5758f1b5323ee525f7c391de11c6ce4c67d2a3e2fe8fbdfcd4f6fa351d6a01324f
7
+ data.tar.gz: 8b153ad0d5f70ebc29fa812efbe4b9e60979060bb3919f185da7b342fb1ce5a50f18ac0b293a1b5de0d17765b21f5ec7e3e35140a2a7d7d352c61dd738fb3f2d
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # Change log
2
+
3
+ ## master
data/LICENSE.txt ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2025 Vladimir Dementyev
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ [![Gem Version](https://badge.fury.io/rb/pglite-rb.svg)](https://rubygems.org/gems/pglite-rb)
2
+ [![Build](https://github.com/palkan/pglite-rb/workflows/Build/badge.svg)](https://github.com/palkan/pglite-rb/actions)
3
+
4
+ # PGlite for Ruby and Rails
5
+
6
+ Let's bring [PGlite](https://pglite.dev/) to Ruby and Rails! Enjoy using PostgreSQL without dealing with databases and native libraries—great for development and testing!
7
+
8
+ ## Installation
9
+
10
+ Add the gem to your Gemfile and run `bundle install`:
11
+
12
+ ```ruby
13
+ # Gemfile
14
+ gem "pglite"
15
+ ```
16
+
17
+ ### Supported Ruby/Rails versions
18
+
19
+ - Ruby (MRI) >= 3.4
20
+ - Rails >= 7.2
21
+
22
+ ## Usage
23
+
24
+ A minimal example:
25
+
26
+ ```ruby
27
+ # First, you must provision the database (creates a bunch of PostgreSQL files in your file system)
28
+ PGlite.install!("tmp/pglite")
29
+
30
+ # Now you can perform queries!
31
+ result = PGLite.exec_query("SELECT 2 + 2 as answer")
32
+
33
+ result.row_count #=> 1
34
+ result.rows #=> [[4]]
35
+ result.columns.map(&:name) #=> ["answer"]
36
+ ```
37
+
38
+ ### Active Record integration
39
+
40
+ Specify the `pglite` adapter in your `database.yml`. Done.
41
+
42
+ The database would be provisioned the first time a connection is initialized (in the `tmp/pglite` directory or in the `mount_path` if one is specified in the configuration). Alternatively, you can manually call `PGlite.install!(path)` on the application boot.
43
+
44
+ ## Configuration
45
+
46
+ You can enable PostgreSQL logs (stdout/stderr) by set the `PGLITE_WASI_STDIO=1` environment variable.
47
+
48
+ ## Contributing
49
+
50
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/palkan/pglite-rb](https://github.com/palkan/pglite-rb).
51
+
52
+ ## Credits
53
+
54
+ This gem is generated via [`newgem` template](https://github.com/palkan/newgem) by [@palkan](https://github.com/palkan).
55
+
56
+ ## License
57
+
58
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
Binary file
Binary file
Binary file
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "pg"
5
+ rescue LoadError
6
+ # Patch #gem to ignore 'pg' checks
7
+ Kernel.prepend(Module.new do
8
+ def gem(dep, *)
9
+ return if dep == "pg"
10
+ super
11
+ end
12
+ end)
13
+
14
+ # Update the $LOAD_PATH to include the pg stub
15
+ $LOAD_PATH.unshift(File.expand_path(File.join(__dir__, "pglite_shims")))
16
+ end
17
+
18
+ require "active_record/connection_adapters/postgresql_adapter"
19
+
20
+ module ActiveRecord
21
+ module ConnectionHandling # :nodoc:
22
+ def pglite_adapter_class
23
+ ConnectionAdapters::PGliteAdapter
24
+ end
25
+
26
+ def pglite_connection(config)
27
+ pglite_adapter_class.new(config)
28
+ end
29
+ end
30
+
31
+ module ConnectionAdapters
32
+ class PGliteAdapter < PostgreSQLAdapter
33
+ class << self
34
+ def database_exists?(config)
35
+ true
36
+ end
37
+
38
+ def new_client(...) = PGlite::Connection.new(...)
39
+ end
40
+
41
+ def initialize(...)
42
+ super
43
+ # Prepared statements are not currently supported
44
+ @prepared_statements = false
45
+ end
46
+
47
+ # Stub encoders/decoders
48
+ def add_pg_encoders = nil
49
+
50
+ def add_pg_decoders = nil
51
+
52
+ unless method_defined?(:query_rows)
53
+ alias_method :query_rows, :query
54
+ end
55
+
56
+ # TODO: col_description is not supported ???
57
+ def column_definitions(table_name)
58
+ query_rows(<<~SQL, "SCHEMA")
59
+ SELECT a.attname, format_type(a.atttypid, a.atttypmod),
60
+ pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
61
+ c.collname, '' AS comment,
62
+ #{supports_identity_columns? ? "attidentity" : quote("")} AS identity,
63
+ #{supports_virtual_columns? ? "attgenerated" : quote("")} as attgenerated
64
+ FROM pg_attribute a
65
+ LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
66
+ LEFT JOIN pg_type t ON a.atttypid = t.oid
67
+ LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
68
+ WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
69
+ AND a.attnum > 0 AND NOT a.attisdropped
70
+ ORDER BY a.attnum
71
+ SQL
72
+ end
73
+
74
+ ::ActiveRecord::Type.add_modifier({array: true}, PostgreSQL::OID::Array, adapter: :pglite)
75
+ ::ActiveRecord::Type.add_modifier({range: true}, PostgreSQL::OID::Range, adapter: :pglite)
76
+ ::ActiveRecord::Type.register(:bit, PostgreSQL::OID::Bit, adapter: :pglite)
77
+ ::ActiveRecord::Type.register(:bit_varying, PostgreSQL::OID::BitVarying, adapter: :pglite)
78
+ ::ActiveRecord::Type.register(:binary, PostgreSQL::OID::Bytea, adapter: :pglite)
79
+ ::ActiveRecord::Type.register(:cidr, PostgreSQL::OID::Cidr, adapter: :pglite)
80
+ ::ActiveRecord::Type.register(:date, PostgreSQL::OID::Date, adapter: :pglite)
81
+ ::ActiveRecord::Type.register(:datetime, PostgreSQL::OID::DateTime, adapter: :pglite)
82
+ ::ActiveRecord::Type.register(:decimal, PostgreSQL::OID::Decimal, adapter: :pglite)
83
+ ::ActiveRecord::Type.register(:enum, PostgreSQL::OID::Enum, adapter: :pglite)
84
+ ::ActiveRecord::Type.register(:hstore, PostgreSQL::OID::Hstore, adapter: :pglite)
85
+ ::ActiveRecord::Type.register(:inet, PostgreSQL::OID::Inet, adapter: :pglite)
86
+ ::ActiveRecord::Type.register(:interval, PostgreSQL::OID::Interval, adapter: :pglite)
87
+ ::ActiveRecord::Type.register(:jsonb, PostgreSQL::OID::Jsonb, adapter: :pglite)
88
+ ::ActiveRecord::Type.register(:money, PostgreSQL::OID::Money, adapter: :pglite)
89
+ ::ActiveRecord::Type.register(:point, PostgreSQL::OID::Point, adapter: :pglite)
90
+ ::ActiveRecord::Type.register(:legacy_point, PostgreSQL::OID::LegacyPoint, adapter: :pglite)
91
+ ::ActiveRecord::Type.register(:uuid, PostgreSQL::OID::Uuid, adapter: :pglite)
92
+ ::ActiveRecord::Type.register(:vector, PostgreSQL::OID::Vector, adapter: :pglite)
93
+ ::ActiveRecord::Type.register(:xml, PostgreSQL::OID::Xml, adapter: :pglite)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pglite/pg"
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pglite/pg"
4
+ require "pglite/result"
5
+
6
+ module PGlite
7
+ class Connection
8
+ attr_reader :mount_path
9
+
10
+ def initialize(conn_params = {})
11
+ @mount_path = conn_params[:mount_path] || File.join(Dir.pwd, "tmp", "pglite")
12
+ @prepared_statements_map = {}
13
+ PGlite.install!(mount_path)
14
+ rescue => e
15
+ raise PG::Error, e.message
16
+ end
17
+
18
+ def set_client_encoding(_)
19
+ # make no-op for now
20
+ end
21
+
22
+ def finished? = true
23
+
24
+ def transaction_status
25
+ PG::PQTRANS_IDLE
26
+ end
27
+
28
+ def escape(str) = str
29
+
30
+ def raw_query(sql, params)
31
+ # FIXME: we need to add support for prepared statements at the extension level
32
+ if params.present?
33
+ raise ArgumentError, "Prepared statements are not supported in pglite"
34
+ end
35
+
36
+ raw_res = PGlite.exec_query(sql)
37
+ result = Result.new(raw_res)
38
+ @last_result = result
39
+ result
40
+ rescue => e
41
+ raise PG::Error, e.message
42
+ end
43
+
44
+ def exec(sql)
45
+ raw_query(sql, [])
46
+ end
47
+
48
+ alias_method :query, :exec
49
+ alias_method :async_exec, :exec
50
+ alias_method :async_query, :exec
51
+
52
+ def exec_params(sql, params)
53
+ if params.empty?
54
+ return exec(sql)
55
+ end
56
+ raw_query(sql, params)
57
+ end
58
+
59
+ def exec_prepared(name, params)
60
+ sql = @prepared_statements_map[name]
61
+ exec_params(sql, params)
62
+ end
63
+
64
+ def prepare(name, sql, param_types = nil)
65
+ @prepared_statements_map[name] = sql
66
+ end
67
+
68
+ def get_last_result
69
+ @last_result
70
+ end
71
+
72
+ def reset
73
+ @prepared_statements_map = {}
74
+ end
75
+
76
+ def server_version
77
+ # The result is formed by multiplying the server's major version number by 10000 and adding the minor version number.
78
+ # For example, version 10.1 will be returned as 100001, and version 11.0 will be returned as 110000.
79
+ PGlite.database_version.match(/PostgreSQL\s(\d+)\.(\d+)/)&.then do
80
+ _1[1].to_i * 10_000 + _1[2].to_i
81
+ end
82
+ end
83
+ end
84
+ end
data/lib/pglite/pg.rb ADDED
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "pg"
5
+ return
6
+ rescue LoadError
7
+ end
8
+
9
+ # Define minumum PG interface
10
+ module PG
11
+ PQTRANS_IDLE = 0 # (connection idle)
12
+ PQTRANS_ACTIVE = 1 # (command in progress)
13
+ PQTRANS_INTRANS = 2 # (idle, within transaction block)
14
+ PQTRANS_INERROR = 3 # (idle, within failed transaction)
15
+ PQTRANS_UNKNOWN = 4 # (cannot determine status)
16
+
17
+ class Error < StandardError; end
18
+ class ConnectionBad < Error; end
19
+ class FeatureNotSupported < Error; end
20
+
21
+ class Connection
22
+ class << self
23
+ # TODO: can we support some configuration?
24
+ def conndefaults_hash = {}
25
+
26
+ def quote_ident(str)
27
+ str = str.to_s
28
+ return '""' if str.empty?
29
+ if str =~ /[^a-zA-Z_0-9]/ || str =~ /^[0-9]/
30
+ '"' + str.gsub('"', '""') + '"'
31
+ else
32
+ str
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ # Just a stub for now
39
+ class SimpleDecoder
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PGlite
4
+ class Result
5
+ attr_reader :res
6
+
7
+ # A wrapper for a result object from Oxide
8
+ def initialize(res)
9
+ @res = res
10
+ end
11
+
12
+ def map_types!(map)
13
+ self
14
+ end
15
+
16
+ def values = res.rows
17
+
18
+ def fields = res.columns.map(&:name)
19
+
20
+ def ftype(index) = res.columns[index].oid
21
+
22
+ def fmod(index) = res.columns[index].type_modifier
23
+
24
+ def cmd_tuples = res.row_count
25
+
26
+ def ntuples = res.row_count
27
+
28
+ def clear
29
+ end
30
+
31
+ include Enumerable
32
+
33
+ def each
34
+ return to_enum(:each) unless block_given?
35
+
36
+ columns = fields
37
+ res.rows.each do |res_row|
38
+ row = {}
39
+ columns.each.with_index do |col, i|
40
+ value = res_row[i]
41
+ row[col] = value
42
+ end
43
+ yield row
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PGlite # :nodoc:
4
+ VERSION = "0.0.4"
5
+ end
data/lib/pglite.rb ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PGlite
4
+ # Main PGlite module
5
+ end
6
+
7
+ require "pglite/version"
8
+
9
+ begin
10
+ require "pglite_rb"
11
+ rescue LoadError
12
+ # Extension not available
13
+ end
14
+
15
+ require "pglite/connection"
16
+
17
+ if defined?(ActiveRecord::ConnectionAdapters) && ActiveRecord::ConnectionAdapters.respond_to?(:register)
18
+ ActiveRecord::ConnectionAdapters.register("pglite", "ActiveRecord::ConnectionAdapters::PGliteAdapter", "active_record/connection_adapters/pglite_adapter")
19
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pglite
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: arm64-darwin
6
+ authors:
7
+ - Vladimir Dementyev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-12-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: combustion
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake-compiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '3.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '3.9'
83
+ description: PGlite for Ruby and Rails
84
+ email:
85
+ - Vladimir Dementyev
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - CHANGELOG.md
91
+ - LICENSE.txt
92
+ - README.md
93
+ - lib/3.2/pglite_rb.bundle
94
+ - lib/3.3/pglite_rb.bundle
95
+ - lib/3.4/pglite_rb.bundle
96
+ - lib/active_record/connection_adapters/pglite_adapter.rb
97
+ - lib/active_record/connection_adapters/pglite_shims/pg.rb
98
+ - lib/pglite.rb
99
+ - lib/pglite/connection.rb
100
+ - lib/pglite/pg.rb
101
+ - lib/pglite/result.rb
102
+ - lib/pglite/version.rb
103
+ homepage: https://github.com/palkan/pglite-rb
104
+ licenses:
105
+ - MIT
106
+ metadata:
107
+ bug_tracker_uri: https://github.com/palkan/pglite-rb/issues
108
+ changelog_uri: https://github.com/palkan/pglite-rb/blob/master/CHANGELOG.md
109
+ documentation_uri: https://github.com/palkan/pglite-rb
110
+ homepage_uri: https://github.com/palkan/pglite-rb
111
+ source_code_uri: https://github.com/palkan/pglite-rb
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '3.2'
121
+ - - "<"
122
+ - !ruby/object:Gem::Version
123
+ version: 3.5.dev
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubygems_version: 3.5.23
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: PGlite for Ruby and Rails
134
+ test_files: []