thingfish-metastore-pg 0.1.0.pre20160627113019
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +1 -0
- data.tar.gz.sig +0 -0
- data/.document +4 -0
- data/.simplecov +9 -0
- data/ChangeLog +95 -0
- data/History.md +4 -0
- data/LICENSE.md +29 -0
- data/Manifest.txt +13 -0
- data/README.md +69 -0
- data/Rakefile +93 -0
- data/data/thingfish-metastore-pg/migrations/20150114_initial.rb +23 -0
- data/lib/thingfish/metastore/pg.rb +305 -0
- data/lib/thingfish/metastore/pg/metadata.rb +154 -0
- data/spec/spec_helper.rb +110 -0
- data/spec/thingfish/metastore/pg_spec.rb +16 -0
- metadata +247 -0
- metadata.gz.sig +1 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d965280761dc25444cd36fb1e0ac88099d5d3c57
|
4
|
+
data.tar.gz: f556f30655cc4012e7dd45cbc4050b2ef4c448e7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aa6c3d6eca82612625762a33eaa1d29076863da10f7f0d04b50a03715c1a6bdc2e806b6e838505e439104018800225119fa118865e094980cef6aa72e990efc8
|
7
|
+
data.tar.gz: f0bdc7e987b43f9cbf9c7415978ddd65d0eaaaf121c919a8934b0e5df16a8a16c1a53e1e86faa536d47bd5f78dcbb1b7db859f947f6de4113eb702a631d0983e
|
checksums.yaml.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
���e�?�Ю�=��`y$����֕�7�F����[�g���'�z��\Z�! 3=�b��]�N?r0�����c9Ǵ}�KXV�%V����xO4���H?Cqܻ�s~J'z�H��yU5�R7���X�Xҧ�@WsL���2la50/���)8��V�Ȋ�L���;�\ix3G���+�&�5_j� �&G7|2Ux�0�$ll���gG��p#K`r�u�>��f��*n9� A;l��M�7��-�����#�_ii�?�ǐG7�b���]�x����ƾ$�O��y�~O�#�y
|
data.tar.gz.sig
ADDED
Binary file
|
data/.document
ADDED
data/.simplecov
ADDED
data/ChangeLog
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
2016-06-27 Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
* .gems, .ruby-gemset, .ruby-version, .rvmrc, Gemfile, History.md,
|
4
|
+
History.rdoc, README.md, README.rdoc, Rakefile, thingfish-metastore-
|
5
|
+
pg.gemspec:
|
6
|
+
Update build env
|
7
|
+
[0a1c87687905] [tip]
|
8
|
+
|
9
|
+
2015-12-14 Michael Granger <ged@FaerieMUD.org>
|
10
|
+
|
11
|
+
* lib/thingfish/metastore/pg.rb,
|
12
|
+
lib/thingfish/metastore/pg/metadata.rb:
|
13
|
+
Consider user metadata for ordering, too
|
14
|
+
[d69c38e41d05] [github/master]
|
15
|
+
|
16
|
+
2015-12-10 Michael Granger <ged@FaerieMUD.org>
|
17
|
+
|
18
|
+
* lib/thingfish/metastore/pg.rb:
|
19
|
+
Don't raise a NoMethodError on missing metadata keys
|
20
|
+
[99ac5402317a]
|
21
|
+
|
22
|
+
* Rakefile:
|
23
|
+
Use latest semantic versioning for the gemspec
|
24
|
+
[7c7236fda1e2]
|
25
|
+
|
26
|
+
2015-11-02 Mahlon E. Smith <mahlon@martini.nu>
|
27
|
+
|
28
|
+
* lib/thingfish/metastore/pg.rb:
|
29
|
+
Rename obsoleted metastore API to correct name.
|
30
|
+
[993664929f87]
|
31
|
+
|
32
|
+
* LICENSE.rdoc, README.rdoc, Rakefile:
|
33
|
+
Fix README and LICENSE file.
|
34
|
+
[e9c83aeb5889]
|
35
|
+
|
36
|
+
2015-04-01 Mahlon E. Smith <mahlon@martini.nu>
|
37
|
+
|
38
|
+
* .gems, .rvm.gems, .rvmrc:
|
39
|
+
Bump development default ruby version, rename rvm gems file.
|
40
|
+
[3e762af58fc9]
|
41
|
+
|
42
|
+
2015-01-29 Michael Granger <ged@FaerieMUD.org>
|
43
|
+
|
44
|
+
* lib/thingfish/metastore/pg.rb:
|
45
|
+
Fix the #apply_search_order method
|
46
|
+
[41dec81585a4]
|
47
|
+
|
48
|
+
* lib/thingfish/metastore/pg.rb:
|
49
|
+
Make the return from #search not use a lazy enumerator.
|
50
|
+
|
51
|
+
It was an interesting experiment, but I don't think it's going to
|
52
|
+
work without retooling the handler to support enumerators.
|
53
|
+
[7e3215bec4f4]
|
54
|
+
|
55
|
+
* lib/thingfish/metastore/pg/metadata.rb:
|
56
|
+
Ensure the "uploadaddress" is a string
|
57
|
+
[e367a26e6d3b]
|
58
|
+
|
59
|
+
* lib/thingfish/metastore/pg.rb:
|
60
|
+
Rearrange the config methods.
|
61
|
+
|
62
|
+
The `::configure` method needs to be below the methods it calls in
|
63
|
+
case it's called upon definition.
|
64
|
+
[485bf6854980]
|
65
|
+
|
66
|
+
* .hgignore:
|
67
|
+
Ignore the package directory.
|
68
|
+
[21423daeb9ce]
|
69
|
+
|
70
|
+
2015-01-28 Michael Granger <ged@FaerieMUD.org>
|
71
|
+
|
72
|
+
* data/thingfish-metastore-pg/migrations/20150114_initial.rb,
|
73
|
+
lib/thingfish/metastore/pg.rb,
|
74
|
+
lib/thingfish/metastore/pg/metadata.rb, spec/spec_helper.rb:
|
75
|
+
Add initial Thingfish::Metastore API
|
76
|
+
[3b0d1b844ad6]
|
77
|
+
|
78
|
+
* .hgignore, .pryrc, Manifest.txt:
|
79
|
+
Update some project files
|
80
|
+
[95106fe17011]
|
81
|
+
|
82
|
+
2015-01-14 Michael Granger <ged@FaerieMUD.org>
|
83
|
+
|
84
|
+
* .rvm.gems, data/thingfish-metastore-
|
85
|
+
pg/migrations/20150114_initial.rb, lib/thingfish/metastore/pg.rb,
|
86
|
+
spec/spec_helper.rb, spec/thingfish/metastore/pg_spec.rb:
|
87
|
+
Got the schema loading and spec helpers set up
|
88
|
+
[62f8eaf03619]
|
89
|
+
|
90
|
+
* .document, .gitignore, .hgignore, .pryrc, .rvm.gems, .rvmrc,
|
91
|
+
.simplecov, History.rdoc, LICENSE.rdoc, README.rdoc, Rakefile,
|
92
|
+
lib/thingfish/metastore/pg.rb, spec/spec_helper.rb,
|
93
|
+
spec/thingfish/metastore/pg_spec.rb:
|
94
|
+
Initial boilerplate
|
95
|
+
[d4cb46c1f0b5]
|
data/History.md
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Copyright (c) 2014-2016, Michael Granger and Mahlon E. Smith.
|
2
|
+
|
3
|
+
All rights reserved.
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without modification, are
|
6
|
+
permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
* Redistributions of source code must retain the above copyright notice, this
|
9
|
+
list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
* Redistributions in binary form must reproduce the above copyright notice, this
|
12
|
+
list of conditions and the following disclaimer in the documentation and/or
|
13
|
+
other materials provided with the distribution.
|
14
|
+
|
15
|
+
* Neither the name of the authors, nor the names of its contributors may be used to
|
16
|
+
endorse or promote products derived from this software without specific prior
|
17
|
+
written permission.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
20
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
21
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
22
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
23
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
24
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
25
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
26
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
27
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
28
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
.document
|
2
|
+
.simplecov
|
3
|
+
ChangeLog
|
4
|
+
History.md
|
5
|
+
LICENSE.md
|
6
|
+
Manifest.txt
|
7
|
+
README.md
|
8
|
+
Rakefile
|
9
|
+
data/thingfish-metastore-pg/migrations/20150114_initial.rb
|
10
|
+
lib/thingfish/metastore/pg.rb
|
11
|
+
lib/thingfish/metastore/pg/metadata.rb
|
12
|
+
spec/spec_helper.rb
|
13
|
+
spec/thingfish/metastore/pg_spec.rb
|
data/README.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# Thingfish PostgreSQL Metastore
|
2
|
+
|
3
|
+
home
|
4
|
+
: https://bitbucket.org/projects/thingfish-metastore-pg
|
5
|
+
|
6
|
+
code
|
7
|
+
: https://bitbucket.org/ged/thingfish-metastore-pg
|
8
|
+
|
9
|
+
github
|
10
|
+
: https://github.com/ged/thingfish-metastore-pg
|
11
|
+
|
12
|
+
docs
|
13
|
+
: https://deveiate.org/code/thingfish-metastore-pg
|
14
|
+
|
15
|
+
|
16
|
+
## Description
|
17
|
+
|
18
|
+
This is a metadata storage plugin for the Thingfish digital asset manager. It provides persistent storage for uploaded data to a PostgreSQL table.
|
19
|
+
|
20
|
+
|
21
|
+
## Authors
|
22
|
+
|
23
|
+
* Michael Granger <ged@FaerieMUD.org>
|
24
|
+
* Mahlon E. Smith <mahlon@martini.nu>
|
25
|
+
|
26
|
+
|
27
|
+
## Installation
|
28
|
+
|
29
|
+
$ gem install thingfish-metastore-pg
|
30
|
+
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
As with Thingfish itself, this plugin uses Configurability[https://rubygems.org/gems/configurability] to modify default behaviors.
|
35
|
+
|
36
|
+
Here's an example configuration file that enables this plugin.
|
37
|
+
|
38
|
+
---
|
39
|
+
thingfish:
|
40
|
+
metastore: pg
|
41
|
+
|
42
|
+
pg_metastore:
|
43
|
+
uri: postgres://thingfish:password@db.example.com/database
|
44
|
+
|
45
|
+
|
46
|
+
When Thingfish starts, it will install the necessary database schema automatically.
|
47
|
+
|
48
|
+
|
49
|
+
## License
|
50
|
+
|
51
|
+
Copyright (c) 2014-2016, Michael Granger and Mahlon E. Smith.
|
52
|
+
|
53
|
+
All rights reserved.
|
54
|
+
|
55
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
56
|
+
|
57
|
+
* Redistributions of source code must retain the above copyright notice, this
|
58
|
+
list of conditions and the following disclaimer.
|
59
|
+
|
60
|
+
* Redistributions in binary form must reproduce the above copyright notice, this
|
61
|
+
list of conditions and the following disclaimer in the documentation and/or
|
62
|
+
other materials provided with the distribution.
|
63
|
+
|
64
|
+
* Neither the name of the authors, nor the names of its contributors may be used to
|
65
|
+
endorse or promote products derived from this software without specific prior
|
66
|
+
written permission.
|
67
|
+
|
68
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
69
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'hoe'
|
5
|
+
rescue LoadError
|
6
|
+
abort "This Rakefile requires hoe (gem install hoe)"
|
7
|
+
end
|
8
|
+
|
9
|
+
GEMSPEC = 'thingfish-metastore-pg.gemspec'
|
10
|
+
|
11
|
+
|
12
|
+
Hoe.plugin :mercurial
|
13
|
+
Hoe.plugin :signing
|
14
|
+
Hoe.plugin :deveiate
|
15
|
+
Hoe.plugin :bundler
|
16
|
+
|
17
|
+
Hoe.plugins.delete :rubyforge
|
18
|
+
Hoe.plugins.delete :gemcutter
|
19
|
+
|
20
|
+
hoespec = Hoe.spec 'thingfish-metastore-pg' do |spec|
|
21
|
+
spec.readme_file = 'README.md'
|
22
|
+
spec.history_file = 'History.md'
|
23
|
+
spec.extra_rdoc_files = FileList[ '*.rdoc', '*.md' ]
|
24
|
+
spec.license 'BSD-3-Clause'
|
25
|
+
spec.urls = {
|
26
|
+
home: 'https://bitbucket.org/ged/thingfish-metastore-pg',
|
27
|
+
code: 'https://bitbucket.org/ged/thingfish-metastore-pg',
|
28
|
+
docs: 'https://deveiate.org/code/thingfish-metastore-pg',
|
29
|
+
github: 'https://github.com/ged/thingfish-metastore-pg',
|
30
|
+
}
|
31
|
+
|
32
|
+
spec.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
33
|
+
spec.developer 'Mahlon E. Smith', 'mahlon@martini.nu'
|
34
|
+
|
35
|
+
spec.dependency 'thingfish', '~> 0.5'
|
36
|
+
spec.dependency 'loggability', '~> 0.10'
|
37
|
+
spec.dependency 'configurability', '~> 2.2'
|
38
|
+
spec.dependency 'sequel', '~> 4.35'
|
39
|
+
spec.dependency 'pg', '~> 0.18'
|
40
|
+
|
41
|
+
spec.dependency 'rspec', '~> 3.0', :developer
|
42
|
+
|
43
|
+
spec.require_ruby_version( '>=2.3.0' )
|
44
|
+
spec.hg_sign_tags = true if spec.respond_to?( :hg_sign_tags= )
|
45
|
+
|
46
|
+
self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
ENV['VERSION'] ||= hoespec.spec.version.to_s
|
51
|
+
|
52
|
+
# Run the tests before checking in
|
53
|
+
task 'hg:precheckin' => [ :check_history, :check_manifest, :gemspec, :spec ]
|
54
|
+
|
55
|
+
# Rebuild the ChangeLog immediately before release
|
56
|
+
task :prerelease => 'ChangeLog'
|
57
|
+
CLOBBER.include( 'ChangeLog' )
|
58
|
+
|
59
|
+
desc "Build a coverage report"
|
60
|
+
task :coverage do
|
61
|
+
ENV["COVERAGE"] = 'yes'
|
62
|
+
Rake::Task[:spec].invoke
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# Use the fivefish formatter for docs generated from development checkout
|
67
|
+
if File.directory?( '.hg' )
|
68
|
+
require 'rdoc/task'
|
69
|
+
|
70
|
+
Rake::Task[ 'docs' ].clear
|
71
|
+
RDoc::Task.new( 'docs' ) do |rdoc|
|
72
|
+
rdoc.main = "README.md"
|
73
|
+
rdoc.rdoc_files.include( "*.rdoc", "*.md", "ChangeLog", "lib/**/*.rb" )
|
74
|
+
rdoc.generator = :fivefish
|
75
|
+
rdoc.title = 'Arborist'
|
76
|
+
rdoc.rdoc_dir = 'doc'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
task :gemspec => GEMSPEC
|
82
|
+
file GEMSPEC => [ __FILE__, 'ChangeLog' ] do |task|
|
83
|
+
spec = $hoespec.spec
|
84
|
+
spec.files.delete( '.gemtest' )
|
85
|
+
spec.signing_key = nil
|
86
|
+
spec.version = "#{spec.version.bump}.0.pre#{Time.now.strftime("%Y%m%d%H%M%S")}"
|
87
|
+
File.open( task.name, 'w' ) do |fh|
|
88
|
+
fh.write( spec.to_ruby )
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
task :default => :gemspec
|
93
|
+
CLOBBER.include( GEMSPEC.to_s )
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# vim: set nosta noet ts=4 sw=4:
|
2
|
+
|
3
|
+
### The initial Thingfish::Metastore::PG DDL.
|
4
|
+
###
|
5
|
+
class Initial < Sequel::Migration
|
6
|
+
|
7
|
+
def up
|
8
|
+
create_schema( :thingfish, if_not_exists: true )
|
9
|
+
create_table( :thingfish__metadata ) do
|
10
|
+
uuid :oid, primary_key: true
|
11
|
+
text :format, null: false
|
12
|
+
int :extent, null: false
|
13
|
+
timestamptz :created, null: false, default: Sequel.function(:now)
|
14
|
+
inet :uploadaddress, null: false
|
15
|
+
jsonb :user_metadata, null: false, default: '{}'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def down
|
20
|
+
drop_table( :thingfish__metadata )
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,305 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
#encoding: utf-8
|
3
|
+
|
4
|
+
require 'loggability'
|
5
|
+
require 'configurability'
|
6
|
+
require 'sequel'
|
7
|
+
require 'strelka'
|
8
|
+
require 'strelka/mixins'
|
9
|
+
|
10
|
+
require 'thingfish'
|
11
|
+
require 'thingfish/mixins'
|
12
|
+
require 'thingfish/metastore'
|
13
|
+
|
14
|
+
# Toplevel namespace
|
15
|
+
class Thingfish::Metastore::PG < Thingfish::Metastore
|
16
|
+
extend Loggability,
|
17
|
+
Configurability,
|
18
|
+
Strelka::MethodUtilities
|
19
|
+
include Thingfish::Normalization
|
20
|
+
|
21
|
+
|
22
|
+
# Load Sequel extensions/plugins
|
23
|
+
Sequel.extension :migration
|
24
|
+
|
25
|
+
|
26
|
+
# Package version
|
27
|
+
VERSION = '0.0.1'
|
28
|
+
|
29
|
+
# Version control revision
|
30
|
+
REVISION = %q$Revision: d69c38e41d05 $
|
31
|
+
|
32
|
+
# The data directory that contains migration files.
|
33
|
+
#
|
34
|
+
DATADIR = if ENV['THINGFISH_METASTORE_PG_DATADIR']
|
35
|
+
Pathname.new( ENV['THINGFISH_METASTORE_PG_DATADIR'] )
|
36
|
+
elsif Gem.datadir( 'thingfish-metastore-pg' )
|
37
|
+
Pathname.new( Gem.datadir('thingfish-metastore-pg') )
|
38
|
+
else
|
39
|
+
Pathname.new( __FILE__ ).dirname.parent.parent.parent +
|
40
|
+
'data' + 'thingfish-metastore-pg'
|
41
|
+
end
|
42
|
+
|
43
|
+
# The default config values
|
44
|
+
DEFAULT_CONFIG = {
|
45
|
+
uri: 'postgres:/thingfish',
|
46
|
+
slow_query_seconds: 0.01,
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
# Loggability API -- use a separate logger
|
51
|
+
log_as :thingfish_metastore_pg
|
52
|
+
|
53
|
+
# Configurability API -- load the `pg_metastore`
|
54
|
+
config_key :pg_metastore
|
55
|
+
|
56
|
+
##
|
57
|
+
# The URI of the database to use for the metastore
|
58
|
+
singleton_attr_accessor :uri
|
59
|
+
|
60
|
+
##
|
61
|
+
# The Sequel::Database that's used to access the metastore tables
|
62
|
+
singleton_attr_accessor :db
|
63
|
+
|
64
|
+
##
|
65
|
+
# The number of seconds to consider a "slow" query
|
66
|
+
singleton_attr_accessor :slow_query_seconds
|
67
|
+
|
68
|
+
|
69
|
+
### Set up the metastore database and migrate to the latest version.
|
70
|
+
def self::setup_database
|
71
|
+
Sequel.extension :pg_json_ops
|
72
|
+
|
73
|
+
self.db = Sequel.connect( self.uri )
|
74
|
+
|
75
|
+
self.db.logger = Loggability[ Thingfish::Metastore::PG ]
|
76
|
+
self.db.sql_log_level = :debug
|
77
|
+
self.db.extension( :pg_json )
|
78
|
+
self.db.log_warn_duration = self.slow_query_seconds
|
79
|
+
|
80
|
+
# Ensure the database is current.
|
81
|
+
#
|
82
|
+
unless Sequel::Migrator.is_current?( self.db, self.migrations_dir.to_s )
|
83
|
+
self.log.info "Installing database schema..."
|
84
|
+
Sequel::Migrator.apply( self.db, self.migrations_dir.to_s )
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
### Tear down the configured metastore database.
|
90
|
+
def self::teardown_database
|
91
|
+
self.log.info "Tearing down database schema..."
|
92
|
+
Sequel::Migrator.apply( self.db, self.migrations_dir.to_s, 0 )
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
### Return the current database migrations directory as a Pathname
|
97
|
+
def self::migrations_dir
|
98
|
+
return DATADIR + 'migrations'
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
### Configurability API -- set up the metastore with the `pg_metastore` section of
|
103
|
+
### the config file.
|
104
|
+
def self::configure( config=nil )
|
105
|
+
config = self.defaults.merge( config || {} )
|
106
|
+
|
107
|
+
self.uri = config[:uri]
|
108
|
+
self.slow_query_seconds = config[:slow_query_seconds]
|
109
|
+
|
110
|
+
self.setup_database
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
### Set up the metastore.
|
115
|
+
def initialize( * ) # :notnew:
|
116
|
+
require 'thingfish/metastore/pg/metadata'
|
117
|
+
Thingfish::Metastore::PG::Metadata.db = self.class.db
|
118
|
+
@model = Thingfish::Metastore::PG::Metadata
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
######
|
123
|
+
public
|
124
|
+
######
|
125
|
+
|
126
|
+
##
|
127
|
+
# The Sequel model representing the metadata rows.
|
128
|
+
attr_reader :model
|
129
|
+
|
130
|
+
|
131
|
+
#
|
132
|
+
# :section: Thingfish::Metastore API
|
133
|
+
#
|
134
|
+
|
135
|
+
### Return an Array of all stored oids.
|
136
|
+
def oids
|
137
|
+
return self.each_oid.to_a
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
### Iterate over each of the store's oids, yielding to the block if one is given
|
142
|
+
### or returning an Enumerator if one is not.
|
143
|
+
def each_oid( &block )
|
144
|
+
return self.model.select_map( :oid ).each( &block )
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
### Save the +metadata+ Hash for the specified +oid+.
|
149
|
+
def save( oid, metadata )
|
150
|
+
md = self.model.from_hash( metadata )
|
151
|
+
md.oid = oid
|
152
|
+
md.save
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
### Fetch the data corresponding to the given +oid+ as a Hash-ish object.
|
157
|
+
def fetch( oid, *keys )
|
158
|
+
metadata = self.model[ oid ] or return nil
|
159
|
+
|
160
|
+
if keys.empty?
|
161
|
+
return metadata.to_hash
|
162
|
+
else
|
163
|
+
keys = normalize_keys( keys )
|
164
|
+
values = metadata.to_hash.values_at( *keys )
|
165
|
+
return Hash[ [keys, values].transpose ]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
### Fetch the value of the metadata associated with the given +key+ for the
|
171
|
+
### specified +oid+.
|
172
|
+
def fetch_value( oid, key )
|
173
|
+
metadata = self.model[ oid ] or return nil
|
174
|
+
key = key.to_sym
|
175
|
+
return metadata[ key ] || metadata.user_metadata[ key ]
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
### Fetch UUIDs related to the given +oid+.
|
180
|
+
def fetch_related_oids( oid )
|
181
|
+
oid = normalize_oid( oid )
|
182
|
+
return self.model.related_to( oid ).select_map( :oid )
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
### Search the metastore for UUIDs which match the specified +criteria+ and
|
187
|
+
### return them as an iterator.
|
188
|
+
def search( options={} )
|
189
|
+
ds = self.model.naked.select( :oid )
|
190
|
+
self.log.debug "Starting search with %p" % [ ds ]
|
191
|
+
|
192
|
+
ds = self.omit_related_resources( ds, options )
|
193
|
+
ds = self.apply_search_criteria( ds, options )
|
194
|
+
ds = self.apply_search_order( ds, options )
|
195
|
+
ds = self.apply_search_direction( ds, options )
|
196
|
+
ds = self.apply_search_limit( ds, options )
|
197
|
+
|
198
|
+
self.log.debug "Dataset for search is: %s" % [ ds.sql ]
|
199
|
+
|
200
|
+
return ds.map {|row| row[:oid] }
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
### Update the metadata for the given +oid+ with the specified +values+ hash.
|
205
|
+
def merge( oid, values )
|
206
|
+
values = normalize_keys( values )
|
207
|
+
|
208
|
+
md = self.model[ oid ] or return nil
|
209
|
+
md.merge!( values )
|
210
|
+
md.save
|
211
|
+
end
|
212
|
+
|
213
|
+
|
214
|
+
### Remove all metadata associated with +oid+ from the Metastore.
|
215
|
+
def remove( oid, *keys )
|
216
|
+
self.model[ oid: oid ].destroy
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
### Remove all metadata associated with +oid+ except for the specified +keys+.
|
221
|
+
def remove_except( oid, *keys )
|
222
|
+
keys = normalize_keys( keys )
|
223
|
+
|
224
|
+
md = self.model[ oid ] or return nil
|
225
|
+
md.user_metadata.keep_if {|key,_| keys.include?(key) }
|
226
|
+
md.save
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
### Returns +true+ if the metastore has metadata associated with the specified +oid+.
|
231
|
+
def include?( oid )
|
232
|
+
return self.model.count( oid: oid ).nonzero?
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
### Returns the number of objects the store contains.
|
237
|
+
def size
|
238
|
+
return self.model.count
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
#########
|
243
|
+
protected
|
244
|
+
#########
|
245
|
+
|
246
|
+
### Omit related resources from the search dataset +ds+ unless the given
|
247
|
+
### +options+ specify otherwise.
|
248
|
+
def omit_related_resources( ds, options )
|
249
|
+
unless options[:include_related]
|
250
|
+
self.log.debug " omitting entries for related resources"
|
251
|
+
ds = ds.unrelated
|
252
|
+
end
|
253
|
+
return ds
|
254
|
+
end
|
255
|
+
|
256
|
+
|
257
|
+
### Apply the search :criteria from the specified +options+ to the collection
|
258
|
+
### in +ds+ and return the modified dataset.
|
259
|
+
def apply_search_criteria( ds, options )
|
260
|
+
if (( criteria = options[:criteria] ))
|
261
|
+
criteria.each do |field, value|
|
262
|
+
self.log.debug " applying criteria: %p => %p" % [ field.to_s, value ]
|
263
|
+
ds = ds.where_metadata( field => value )
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
return ds
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
### Apply the search :order from the specified +options+ to the collection in
|
272
|
+
### +ds+ and return the modified dataset.
|
273
|
+
def apply_search_order( ds, options )
|
274
|
+
if options[:order]
|
275
|
+
columns = Array( options[:order] )
|
276
|
+
self.log.debug " ordering results by columns: %p" % [ columns ]
|
277
|
+
ds = ds.order_metadata( columns )
|
278
|
+
end
|
279
|
+
|
280
|
+
return ds
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
### Apply the search :direction from the specified +options+ to the collection
|
285
|
+
### in +ds+ and return the modified dataset.
|
286
|
+
def apply_search_direction( ds, options )
|
287
|
+
ds = ds.reverse if options[:direction] && options[:direction] == 'desc'
|
288
|
+
return ds
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
### Apply the search :limit from the specified +options+ to the collection in
|
293
|
+
### +ds+ and return the modified dataset.
|
294
|
+
def apply_search_limit( ds, options )
|
295
|
+
if (( limit = options[:limit] ))
|
296
|
+
self.log.debug " limiting to %s results" % [ limit ]
|
297
|
+
offset = options[:offset] || 0
|
298
|
+
ds = ds.limit( limit, offset )
|
299
|
+
end
|
300
|
+
|
301
|
+
return ds
|
302
|
+
end
|
303
|
+
|
304
|
+
end # class Thingfish::Metastore::PG
|
305
|
+
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
#encoding: utf-8
|
3
|
+
|
4
|
+
require 'sequel/model'
|
5
|
+
|
6
|
+
require 'thingfish/mixins'
|
7
|
+
require 'thingfish/metastore/pg' unless defined?( Thingfish::Metastore::PG )
|
8
|
+
|
9
|
+
|
10
|
+
# A row of metadata describing an asset in a Thingfish store.
|
11
|
+
class Thingfish::Metastore::PG::Metadata < Sequel::Model( :thingfish__metadata )
|
12
|
+
include Thingfish::Normalization
|
13
|
+
|
14
|
+
# Allow instances to be created with a primary key
|
15
|
+
unrestrict_primary_key
|
16
|
+
|
17
|
+
|
18
|
+
# Dataset methods
|
19
|
+
dataset_module do
|
20
|
+
|
21
|
+
### Dataset method: Limit results to metadata which is for a related resource.
|
22
|
+
def related
|
23
|
+
return self.exclude( self.user_metadata_expr('relation') => nil )
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
### Dataset method: Limit results to metadata which is not for a related resource.
|
28
|
+
def unrelated
|
29
|
+
return self.where_metadata( relation: nil )
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
### Return a dataset which will select metadata of resources related to the
|
34
|
+
### resource with the given +oid+.
|
35
|
+
def related_to( oid )
|
36
|
+
oid = oid.oid if oid.respond_to?( :oid ) # Support query by model object
|
37
|
+
oid = Thingfish::Normalization.normalize_oid( oid )
|
38
|
+
|
39
|
+
return self.where_metadata( relation: oid )
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
### Dataset method: Limit results to records whose operational or user
|
44
|
+
### metadata matches the values from the specified +hash+.
|
45
|
+
def where_metadata( hash )
|
46
|
+
ds = self
|
47
|
+
hash.each do |field, value|
|
48
|
+
if Thingfish::Metastore::PG::Metadata.metadata_columns.include?( field.to_sym )
|
49
|
+
ds = ds.where( field.to_sym => value )
|
50
|
+
else
|
51
|
+
ds = ds.where( self.user_metadata_expr(field) => value )
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
return ds
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
### Dataset method: Order results by the specified +columns+.
|
60
|
+
def order_metadata( *columns )
|
61
|
+
columns.flatten!
|
62
|
+
ds = self
|
63
|
+
columns.each do |column|
|
64
|
+
if Thingfish::Metastore::PG::Metadata.metadata_columns.include?( column.to_sym )
|
65
|
+
ds = ds.order_append( column.to_sym )
|
66
|
+
else
|
67
|
+
ds = ds.order_append( self.user_metadata_expr(column) )
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
return ds
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
#########
|
76
|
+
protected
|
77
|
+
#########
|
78
|
+
|
79
|
+
### Returns a Sequel expression suitable for use as the key of a query against
|
80
|
+
### the specified user metadata field.
|
81
|
+
def user_metadata_expr( field )
|
82
|
+
return Sequel.pg_jsonb( :user_metadata ).get_text( field.to_s )
|
83
|
+
end
|
84
|
+
|
85
|
+
end # dataset_module
|
86
|
+
|
87
|
+
|
88
|
+
### Return a new Metadata object from the given +oid+ and one-dimensional +hash+
|
89
|
+
### used by Thingfish.
|
90
|
+
def self::from_hash( hash )
|
91
|
+
metadata = Thingfish::Normalization.normalize_keys( hash )
|
92
|
+
|
93
|
+
md = new
|
94
|
+
|
95
|
+
md.format = metadata.delete( 'format' )
|
96
|
+
md.extent = metadata.delete( 'extent' )
|
97
|
+
md.created = metadata.delete( 'created' )
|
98
|
+
md.uploadaddress = metadata.delete( 'uploadaddress' ).to_s
|
99
|
+
|
100
|
+
md.user_metadata = Sequel.pg_jsonb( metadata )
|
101
|
+
|
102
|
+
return md
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
### Return the columns of the table that are used for resource metadata.
|
107
|
+
def self::metadata_columns
|
108
|
+
return self.columns - [self.primary_key, :user_metadata]
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
### Do some initial attribute setup for new objects.
|
113
|
+
def initialize( * )
|
114
|
+
super
|
115
|
+
self[ :user_metadata ] ||= Sequel.pg_jsonb({})
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
### Return the metadata as a Hash; overridden from Sequel::Model to
|
120
|
+
### merge the user and system pairs together.
|
121
|
+
def to_hash
|
122
|
+
hash = self.values
|
123
|
+
|
124
|
+
hash.delete( :oid )
|
125
|
+
hash.merge!( hash.delete(:user_metadata) )
|
126
|
+
|
127
|
+
return normalize_keys( hash )
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
### Merge new metadata +values+ into the metadata for the resource
|
132
|
+
def merge!( values )
|
133
|
+
|
134
|
+
# Extract and set the column-metadata values first
|
135
|
+
self.class.metadata_columns.each do |col|
|
136
|
+
next unless values.key?( col.to_s )
|
137
|
+
self[ col ] = values.delete( col.to_s )
|
138
|
+
end
|
139
|
+
|
140
|
+
self.user_metadata.merge!( values )
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
#########
|
145
|
+
protected
|
146
|
+
#########
|
147
|
+
|
148
|
+
### Proxy method -- fetch a value from the metadata hash if it exists.
|
149
|
+
def method_missing( sym, *args, &block )
|
150
|
+
return self.user_metadata[ sym.to_s ] || super
|
151
|
+
end
|
152
|
+
|
153
|
+
end # Thingfish::Metastore::PG::Metadata
|
154
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
BEGIN {
|
5
|
+
require 'pathname'
|
6
|
+
basedir = Pathname( __FILE__ ).dirname.parent
|
7
|
+
|
8
|
+
thingfishdir = basedir.parent + 'Thingfish'
|
9
|
+
thingfishlib = thingfishdir + 'lib'
|
10
|
+
|
11
|
+
$LOAD_PATH.unshift( thingfishlib.to_s ) if thingfishlib.exist?
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
# SimpleCov test coverage reporting; enable this using the :coverage rake task
|
16
|
+
require 'simplecov' if ENV['COVERAGE']
|
17
|
+
|
18
|
+
require 'loggability'
|
19
|
+
require 'loggability/spechelpers'
|
20
|
+
require 'configurability'
|
21
|
+
require 'configurability/behavior'
|
22
|
+
|
23
|
+
require 'rspec'
|
24
|
+
require 'thingfish'
|
25
|
+
require 'thingfish/spechelpers'
|
26
|
+
require 'thingfish/behaviors'
|
27
|
+
require 'thingfish/metastore'
|
28
|
+
|
29
|
+
Loggability.format_with( :color ) if $stdout.tty?
|
30
|
+
|
31
|
+
# Some helper functions for testing. Usage:
|
32
|
+
#
|
33
|
+
# # in spec/spec_helper.rb
|
34
|
+
# RSpec.configure do |c|
|
35
|
+
# c.include( Thingfish::Metastore::PG::SpecHelpers )
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # in my_class_spec.rb; mark an example as needing database setup
|
39
|
+
# describe MyClass, db: true do
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
module Thingfish::MetastorePGSpecHelpers
|
43
|
+
|
44
|
+
TESTDB_ENV_VAR = 'THINGFISH_DB_URI'
|
45
|
+
|
46
|
+
### Inclusion callback -- install some hooks
|
47
|
+
def self::included( context )
|
48
|
+
|
49
|
+
context.before( :all ) do
|
50
|
+
if ((db_uri = ENV[ TESTDB_ENV_VAR ]))
|
51
|
+
Thingfish::Metastore::PG.configure( uri: db_uri )
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context.after( :all ) do
|
56
|
+
Thingfish::Metastore::PG.teardown_database if Thingfish::Metastore::PG.db
|
57
|
+
end
|
58
|
+
|
59
|
+
context.around( :each ) do |example|
|
60
|
+
if (( setting = example.metadata[:db] ))
|
61
|
+
Loggability[ Thingfish::Metastore::PG ].debug "DB setting: %p" % [ setting ]
|
62
|
+
|
63
|
+
if ((db = Thingfish::Metastore::PG.db))
|
64
|
+
if setting == :no_transaction || setting == :without_transaction
|
65
|
+
Loggability[ Thingfish::Metastore::PG ].debug " running without a transaction"
|
66
|
+
example.run
|
67
|
+
else
|
68
|
+
Loggability[ Thingfish::Metastore::PG ].debug " running with a transaction"
|
69
|
+
db.transaction( rollback: :always ) do
|
70
|
+
example.run
|
71
|
+
end
|
72
|
+
end
|
73
|
+
elsif setting.to_s == 'pending'
|
74
|
+
example.metadata[:pending] ||=
|
75
|
+
"a configured database URI in #{TESTDB_ENV_VAR}"
|
76
|
+
else
|
77
|
+
fail "No database connection! " +
|
78
|
+
"Ensure you have the #{TESTDB_ENV_VAR} ENV variable set to " +
|
79
|
+
"the URI of an (empty) test database you have write permissions to."
|
80
|
+
end
|
81
|
+
else
|
82
|
+
example.run
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
super
|
87
|
+
end
|
88
|
+
|
89
|
+
end # module Thingfish::Metastore::PG::SpecHelpers
|
90
|
+
|
91
|
+
|
92
|
+
### Mock with RSpec
|
93
|
+
RSpec.configure do |c|
|
94
|
+
include Thingfish::SpecHelpers
|
95
|
+
include Thingfish::SpecHelpers::Constants
|
96
|
+
|
97
|
+
c.run_all_when_everything_filtered = true
|
98
|
+
c.filter_run :focus
|
99
|
+
# c.order = 'random'
|
100
|
+
c.mock_with( :rspec ) do |mock|
|
101
|
+
mock.syntax = :expect
|
102
|
+
end
|
103
|
+
|
104
|
+
c.include( Loggability::SpecHelpers )
|
105
|
+
c.include( Thingfish::SpecHelpers )
|
106
|
+
c.include( Thingfish::MetastorePGSpecHelpers )
|
107
|
+
end
|
108
|
+
|
109
|
+
# vim: set nosta noet ts=4 sw=4:
|
110
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd
|
2
|
+
#encoding: utf-8
|
3
|
+
|
4
|
+
require_relative '../../spec_helper'
|
5
|
+
|
6
|
+
require 'rspec'
|
7
|
+
|
8
|
+
require 'thingfish/behaviors'
|
9
|
+
require 'thingfish/metastore/pg'
|
10
|
+
|
11
|
+
describe Thingfish::Metastore::PG, db: true do
|
12
|
+
|
13
|
+
it_should_behave_like "a Thingfish metastore"
|
14
|
+
|
15
|
+
end
|
16
|
+
|
metadata
ADDED
@@ -0,0 +1,247 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: thingfish-metastore-pg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.pre20160627113019
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Granger
|
8
|
+
- Mahlon E. Smith
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain:
|
12
|
+
- |
|
13
|
+
-----BEGIN CERTIFICATE-----
|
14
|
+
MIIEbDCCAtSgAwIBAgIBATANBgkqhkiG9w0BAQsFADA+MQwwCgYDVQQDDANnZWQx
|
15
|
+
GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
16
|
+
HhcNMTYwODIwMTgxNzQyWhcNMTcwODIwMTgxNzQyWjA+MQwwCgYDVQQDDANnZWQx
|
17
|
+
GTAXBgoJkiaJk/IsZAEZFglGYWVyaWVNVUQxEzARBgoJkiaJk/IsZAEZFgNvcmcw
|
18
|
+
ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC/JWGRHO+USzR97vXjkFgt
|
19
|
+
83qeNf2KHkcvrRTSnR64i6um/ziin0I0oX23H7VYrDJC9A/uoUa5nGRJS5Zw/+wW
|
20
|
+
ENcvWVZS4iUzi4dsYJGY6yEOsXh2CcF46+QevV8iE+UmbkU75V7Dy1JCaUOyizEt
|
21
|
+
TH5UHsOtUU7k9TYARt/TgYZKuaoAMZZd5qyVqhF1vV+7/Qzmp89NGflXf2xYP26a
|
22
|
+
4MAX2qqKX/FKXqmFO+AGsbwYTEds1mksBF3fGsFgsQWxftG8GfZQ9+Cyu2+l1eOw
|
23
|
+
cZ+lPcg834G9DrqW2zhqUoLr1MTly4pqxYGb7XoDhoR7dd1kFE2a067+DzWC/ADt
|
24
|
+
+QkcqWUm5oh1fN0eqr7NsZlVJDulFgdiiYPQiIN7UNsii4Wc9aZqBoGcYfBeQNPZ
|
25
|
+
soo/6za/bWajOKUmDhpqvaiRv9EDpVLzuj53uDoukMMwxCMfgb04+ckQ0t2G7wqc
|
26
|
+
/D+K9JW9DDs3Yjgv9k4h7YMhW5gftosd+NkNC/+Y2CkCAwEAAaN1MHMwCQYDVR0T
|
27
|
+
BAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFHKN/nkRusdqCJEuq3lgB3fJvyTg
|
28
|
+
MBwGA1UdEQQVMBOBEWdlZEBGYWVyaWVNVUQub3JnMBwGA1UdEgQVMBOBEWdlZEBG
|
29
|
+
YWVyaWVNVUQub3JnMA0GCSqGSIb3DQEBCwUAA4IBgQAPJzKiT0zBU7kpqe0aS2qb
|
30
|
+
FI0PJ4y5I8buU4IZGUD5NEt/N7pZNfOyBxkrZkXhS44Fp+xwBH5ebLbq/WY78Bqd
|
31
|
+
db0z6ZgW4LMYMpWFfbXsRbd9TU2f52L8oMAhxOvF7Of5qJMVWuFQ8FPagk2iHrdH
|
32
|
+
inYLQagqAF6goWTXgAJCdPd6SNeeSNqA6vlY7CV1Jh5kfNJJ6xu/CVij1GzCLu/5
|
33
|
+
DMOr26DBv+qLJRRC/2h34uX71q5QgeOyxvMg+7V3u/Q06DXyQ2VgeeqiwDFFpEH0
|
34
|
+
PFkdPO6ZqbTRcLfNH7mFgCBJjsfSjJrn0sPBlYyOXgCoByfZnZyrIMH/UY+lgQqS
|
35
|
+
6Von1VDsfQm0eJh5zYZD64ZF86phSR7mUX3mXItwH04HrZwkWpvgd871DZVR3i1n
|
36
|
+
w8aNA5re5+Rt/Vvjxj5AcEnZnZiz5x959NaddQocX32Z1unHw44pzRNUur1GInfW
|
37
|
+
p4vpx2kUSFSAGjtCbDGTNV2AH8w9OU4xEmNz8c5lyoA=
|
38
|
+
-----END CERTIFICATE-----
|
39
|
+
date: 2016-06-27 00:00:00.000000000 Z
|
40
|
+
dependencies:
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thingfish
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.5'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: loggability
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.10'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.10'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: configurability
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.2'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sequel
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.35'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '4.35'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pg
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.18'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.18'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: hoe-mercurial
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.4'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.4'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: hoe-deveiate
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.8'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.8'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: hoe-highline
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.2'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.2'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rdoc
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '4.0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '4.0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rspec
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '3.0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '3.0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: hoe
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '3.15'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '3.15'
|
195
|
+
description: This is a metadata storage plugin for the Thingfish digital asset manager.
|
196
|
+
It provides persistent storage for uploaded data to a PostgreSQL table.
|
197
|
+
email:
|
198
|
+
- ged@FaerieMUD.org
|
199
|
+
- mahlon@martini.nu
|
200
|
+
executables: []
|
201
|
+
extensions: []
|
202
|
+
extra_rdoc_files:
|
203
|
+
- History.md
|
204
|
+
- LICENSE.md
|
205
|
+
- Manifest.txt
|
206
|
+
- README.md
|
207
|
+
files:
|
208
|
+
- ".document"
|
209
|
+
- ".simplecov"
|
210
|
+
- ChangeLog
|
211
|
+
- History.md
|
212
|
+
- LICENSE.md
|
213
|
+
- Manifest.txt
|
214
|
+
- README.md
|
215
|
+
- Rakefile
|
216
|
+
- data/thingfish-metastore-pg/migrations/20150114_initial.rb
|
217
|
+
- lib/thingfish/metastore/pg.rb
|
218
|
+
- lib/thingfish/metastore/pg/metadata.rb
|
219
|
+
- spec/spec_helper.rb
|
220
|
+
- spec/thingfish/metastore/pg_spec.rb
|
221
|
+
homepage: https://bitbucket.org/ged/thingfish-metastore-pg
|
222
|
+
licenses:
|
223
|
+
- BSD-3-Clause
|
224
|
+
metadata: {}
|
225
|
+
post_install_message:
|
226
|
+
rdoc_options:
|
227
|
+
- "--main"
|
228
|
+
- README.md
|
229
|
+
require_paths:
|
230
|
+
- lib
|
231
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - ">="
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: 2.3.0
|
236
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
|
+
requirements:
|
238
|
+
- - ">"
|
239
|
+
- !ruby/object:Gem::Version
|
240
|
+
version: 1.3.1
|
241
|
+
requirements: []
|
242
|
+
rubyforge_project:
|
243
|
+
rubygems_version: 2.5.1
|
244
|
+
signing_key:
|
245
|
+
specification_version: 4
|
246
|
+
summary: This is a metadata storage plugin for the Thingfish digital asset manager
|
247
|
+
test_files: []
|
metadata.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
``�b��qV7Q��µY�Oz�R8B����?Ī'��m���3�6N[�^��I!E�ظR&vk��K���#�I6�<���'�w�R�)od�����A���<3�� �����2�H�M�w}A�x�v$���نQ�vV.�E��b�Lv�BE1���������9(�������j��pz@�i)�mȴ���c��^BdHUz��Yu-@zF[�ңQĩ$}�3�Ɏ�K�F��2P3P��a�8��2�E���y���x4p>�<�;ƘJ�^�^DB~i�K�@�����h�R/�� ��x�@́�M�aD����/`��B���J*ES�8�Svz�i7��g��&ZV���.��Bm�+<�c��\g�=�
|