Skip to content

Instantly share code, notes, and snippets.

@inopinatus
Last active December 19, 2015 09:09
Show Gist options
  • Save inopinatus/5930884 to your computer and use it in GitHub Desktop.
Save inopinatus/5930884 to your computer and use it in GitHub Desktop.
hstore array test code
require 'bundler'
Bundler.setup(:default)
require 'active_record'
require 'minitest/autorun'
require 'logger'
ActiveRecord::Base.establish_connection(adapter: 'postgresql', database: 'testapp_development')
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
enable_extension "hstore" # connection role must be a superuser
create_table :servers do |t|
t.string :name
t.string :admins, :array => true
t.hstore :properties
t.hstore :interfaces, :array => true
end
end
class Server < ActiveRecord::Base
store_accessor :properties, :cpu, :colour
scope :where_any, ->(column, key, value) { where("? IN (SELECT unnest(\"#{column}\") -> ?)", value, key) }
scope :where_all, ->(column, key, value) { where("? = ALL (SELECT unnest(\"#{column}\") -> ?)", value, key) }
end
class BugTest < Minitest::Test
def test_hstore_arrays
server = Server.create!
server.name = "example"
server.save! # ok
assert_equal(nil, server.cpu)
assert_equal(nil, server.colour)
assert_equal(nil, server.interfaces)
server.admins = %w(charlie misha mitsuki)
server.save! # ok, so array types are fine
server.cpu = "xeon"
server.colour = "beige"
server.save! # ok, hstore is working
server.interfaces = []
server.save! # ok, so an empty array works, but ...
server.reload
assert_equal([], server.interfaces)
server.interfaces = [
{ name: "bge0", ipv4: "192.0.2.2", state: "up" },
{ name: "de0", state: "disabled", by: "misha" },
{ name: "magic0", "note" => "' \\ \" { ] } [" },
{ name: "fe0", state: "up" },
]
server.save! # goes BOOM! here in rails 4.0.0 due to incorrect encoding
# works with fix in place:
server.reload
assert_equal("up", server.interfaces[0][:state])
assert_equal("' \\ \" { ] } [", server.interfaces[2][:note])
# hstore queries work
server = Server.where("properties -> 'cpu' = 'xeon'").first
assert_equal("example", server.name)
# array queries work
server = Server.where("'charlie' = ANY (admins)").first
assert_equal("example", server.name)
# hstore queries work against array elements
server = Server.where("interfaces[1] -> 'state' = 'up'").first
assert_equal("example", server.name)
# array searching works
srvs = Server.where_any(:interfaces, :state, "up")
assert_equal("example", srvs.first.name)
assert_equal(1, srvs.count)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment