hanami-sequel 1.1.0.1
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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +119 -0
- data/LICENSE +674 -0
- data/README.md +129 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/hanami-sequel.gemspec +38 -0
- data/lib/hanami/sequel.rb +3 -0
- data/lib/hanami/sequel/cli.rb +62 -0
- data/lib/hanami/sequel/commands/create.rb +31 -0
- data/lib/hanami/sequel/commands/drop.rb +31 -0
- data/lib/hanami/sequel/commands/install.rb +16 -0
- data/lib/hanami/sequel/commands/migrate.rb +42 -0
- data/lib/hanami/sequel/commands/migration.rb +23 -0
- data/lib/hanami/sequel/commands/model.rb +48 -0
- data/lib/hanami/sequel/commands/seed.rb +37 -0
- data/lib/hanami/sequel/configuration.rb +11 -0
- data/lib/hanami/sequel/model.rb +3 -0
- data/lib/hanami/sequel/templates/migration.erb +6 -0
- data/lib/hanami/sequel/templates/model-migration.erb +10 -0
- data/lib/hanami/sequel/templates/model-sequel.erb +14 -0
- data/lib/hanami/sequel/templates/model-spec.erb +3 -0
- data/lib/hanami/sequel/version.rb +5 -0
- metadata +142 -0
data/README.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# Hanami::Sequel
|
2
|
+
|
3
|
+
This gem is designed to replace the `hanami-model` one in your
|
4
|
+
[Hanami](https://hanamirb.org/) project. It adds an equivalent set of database
|
5
|
+
commands to the `hanami` executable, and generates Sequel models.
|
6
|
+
|
7
|
+
Please note that using this gem could be considered bad practice with regards
|
8
|
+
to Hanami's architectural goals, as it does not provide any help to separate
|
9
|
+
the model into entities and repositories. On the other hand, it does nothing to
|
10
|
+
prevent it either.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Follow the instructions for removing `hanami-model`:
|
15
|
+
[Use Your Own ORM](http://hanamirb.org/guides/1.1/models/use-your-own-orm/)
|
16
|
+
|
17
|
+
Add this line to your `config/environment.rb`:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require "hamani/sequel/model"
|
21
|
+
```
|
22
|
+
|
23
|
+
Add this line to your application's Gemfile (adding the gem to the `plugins`
|
24
|
+
group ensures that the `hanami` executable is correctly extended):
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
group :plugins do
|
28
|
+
gem 'hanami-sequel', '~> 1.1.0'
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
And then execute:
|
33
|
+
|
34
|
+
$ bundle
|
35
|
+
|
36
|
+
## Versioning
|
37
|
+
|
38
|
+
This gem's version is based on the major and minor versions of Hanami. For
|
39
|
+
`hanami-X.Y.Z`, use `hanami-sequel-X.Y.P`. This gem's patch version (denoted as
|
40
|
+
`P`) is independent from Hanami's patch version (denoted as `Z`).
|
41
|
+
|
42
|
+
## Configuration
|
43
|
+
|
44
|
+
As of now, the paths to migrations and models are hardcoded respectively to
|
45
|
+
`db/migrations/` and `lib/#{project_name}/models/`.
|
46
|
+
|
47
|
+
## Usage
|
48
|
+
|
49
|
+
All the commands start with the `sequel` argument:
|
50
|
+
|
51
|
+
```text
|
52
|
+
Commands:
|
53
|
+
hanami sequel create
|
54
|
+
hanami sequel drop
|
55
|
+
hanami sequel install
|
56
|
+
hanami sequel migrate [VERSION]
|
57
|
+
hanami sequel migration NAME
|
58
|
+
hanami sequel model NAME
|
59
|
+
hanami sequel seed
|
60
|
+
```
|
61
|
+
|
62
|
+
#### Create a database table
|
63
|
+
|
64
|
+
$ hanami sequel model NAME
|
65
|
+
|
66
|
+
Where `NAME` is the name of the model. This creates a database migration, a
|
67
|
+
Sequel model and a spec file.
|
68
|
+
|
69
|
+
#### Create a database migration
|
70
|
+
|
71
|
+
$ hanami sequel migration NAME
|
72
|
+
|
73
|
+
Where `NAME` is an arbitrary name.
|
74
|
+
|
75
|
+
#### Create the database
|
76
|
+
|
77
|
+
$ hanami sequel create
|
78
|
+
|
79
|
+
This command will fail in the `production` environment.
|
80
|
+
|
81
|
+
#### Migrate the database
|
82
|
+
|
83
|
+
$ hanami sequel migrate [VERSION]
|
84
|
+
|
85
|
+
Where `VERSION` can be:
|
86
|
+
|
87
|
+
* "up" (default value), to do all the migrations, i.e. `hanami sequel migrate`
|
88
|
+
or `hanami sequel migrate up`.
|
89
|
+
* "down", to undo all the migrations, i.e. `hanami sequel migrate down`.
|
90
|
+
* a timestamp, representing the first part of the target migration file. E.g.
|
91
|
+
`hanami sequel migrate 20180201153930` to migrate to the database version as
|
92
|
+
of 1st February 2018 at 15:39:30 (if a migration file starting with this
|
93
|
+
value is found).
|
94
|
+
|
95
|
+
#### Seed the database
|
96
|
+
|
97
|
+
$ hanami sequel seed
|
98
|
+
|
99
|
+
This command will look up your models for `Hanami:Sequel:Seed` class methods
|
100
|
+
used to import constants into your tables. If an error occurs, the whole `seed`
|
101
|
+
operation will be rolled back.
|
102
|
+
|
103
|
+
#### Drop the database
|
104
|
+
|
105
|
+
$ hanami sequel drop
|
106
|
+
|
107
|
+
This command will fail in the `production` environment.
|
108
|
+
|
109
|
+
#### Install the database
|
110
|
+
|
111
|
+
$ hanami sequel install
|
112
|
+
|
113
|
+
This command `drop`s, `create`s, `migrate`s, then `seed`s your database. It will fail in
|
114
|
+
the `production` environment.
|
115
|
+
|
116
|
+
## Development
|
117
|
+
|
118
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
119
|
+
|
120
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
121
|
+
|
122
|
+
## Known issues / To-do list
|
123
|
+
|
124
|
+
* hardcoded configuration values
|
125
|
+
* no tests
|
126
|
+
|
127
|
+
## Contributing
|
128
|
+
|
129
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/malin-as/hanami-sequel.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "hanami/sequel"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "hanami/sequel/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hanami-sequel"
|
8
|
+
spec.version = Hanami::Sequel::VERSION
|
9
|
+
spec.authors = ["Malina Sulca"]
|
10
|
+
spec.email = ["malina.sulca@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Integration of Sequel into Hanami.}
|
13
|
+
spec.description = %q{Integrates Sequel into Hanami by providing database commands and generating model files.}
|
14
|
+
spec.homepage = "https://github.com/malin-as/hanami-sequel.git"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
20
|
+
else
|
21
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
22
|
+
"public gem pushes."
|
23
|
+
end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
26
|
+
f.match(%r{^(test|spec|features)/})
|
27
|
+
end
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
33
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
34
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
35
|
+
|
36
|
+
spec.add_dependency "sequel", "~> 5.0"
|
37
|
+
spec.add_dependency "hanami", "~> 1.1.0"
|
38
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module Sequel
|
5
|
+
module CLI
|
6
|
+
def self.hanamirc
|
7
|
+
@hanamirc ||= Hanamirc.new(Pathname.new('.'))
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.lib_path
|
11
|
+
@lib_path ||= "lib/#{hanamirc.options[:project]}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.models_path
|
15
|
+
@models_path ||= File.join(lib_path, 'models')
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.spec_path
|
19
|
+
@spec_path ||= "spec/#{hanamirc.options[:project]}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.config
|
23
|
+
@config ||= Hanami::Sequel::Configuration.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.template(name)
|
27
|
+
File.join(File.dirname(__FILE__), 'templates', "#{name}.erb")
|
28
|
+
end
|
29
|
+
|
30
|
+
class ErBinding
|
31
|
+
def initialize(**vars)
|
32
|
+
@vars = vars
|
33
|
+
end
|
34
|
+
|
35
|
+
def bind
|
36
|
+
@vars.each_with_object(binding) do |(k, v), b|
|
37
|
+
b.local_variable_set(k.to_sym, v)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.generate(template, erbinding, destination)
|
43
|
+
raise "File #{destination} already exists" if File.exist?(destination)
|
44
|
+
|
45
|
+
dirname = File.dirname(destination)
|
46
|
+
FileUtils.mkdir_p(dirname) unless Dir.exist?(dirname)
|
47
|
+
|
48
|
+
content = ERB.new(File.read(template))
|
49
|
+
.result(erbinding&.bind)
|
50
|
+
File.write(destination, content)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
require_relative 'commands/create'
|
57
|
+
require_relative 'commands/drop'
|
58
|
+
require_relative 'commands/install'
|
59
|
+
require_relative 'commands/migrate'
|
60
|
+
require_relative 'commands/migration'
|
61
|
+
require_relative 'commands/model'
|
62
|
+
require_relative 'commands/seed'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Hanami
|
2
|
+
module Sequel
|
3
|
+
module CLI
|
4
|
+
class Create < Hanami::CLI::Command
|
5
|
+
def call(**options)
|
6
|
+
Command.create
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Command
|
12
|
+
def self.create
|
13
|
+
env = Hanami::Environment.new
|
14
|
+
if env.environment == 'production'
|
15
|
+
raise 'Command unavailable in the production environment.'
|
16
|
+
end
|
17
|
+
|
18
|
+
db_url = ENV.fetch('DATABASE_URL')
|
19
|
+
db_conn, _, db_name = db_url.rpartition('/')
|
20
|
+
|
21
|
+
require 'sequel'
|
22
|
+
|
23
|
+
db = ::Sequel.connect("#{db_conn}/postgres",
|
24
|
+
loggers: Logger.new($stdout))
|
25
|
+
db.run("CREATE DATABASE #{db_name}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Hanami::CLI.register 'sequel create', Hanami::Sequel::CLI::Create
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Hanami
|
2
|
+
module Sequel
|
3
|
+
module CLI
|
4
|
+
class Drop < Hanami::CLI::Command
|
5
|
+
def call(**options)
|
6
|
+
Command.drop
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Command
|
12
|
+
def self.drop
|
13
|
+
env = Hanami::Environment.new
|
14
|
+
if env.environment == 'production'
|
15
|
+
raise 'Command unavailable in the production environment.'
|
16
|
+
end
|
17
|
+
|
18
|
+
db_url = ENV.fetch('DATABASE_URL')
|
19
|
+
db_conn, _, db_name = db_url.rpartition('/')
|
20
|
+
|
21
|
+
require 'sequel'
|
22
|
+
|
23
|
+
db = ::Sequel.connect("#{db_conn}/postgres",
|
24
|
+
loggers: Logger.new($stdout))
|
25
|
+
db.run("DROP DATABASE IF EXISTS #{db_name}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Hanami::CLI.register 'sequel drop', Hanami::Sequel::CLI::Drop
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Hanami
|
2
|
+
module Sequel
|
3
|
+
module CLI
|
4
|
+
class Install < Hanami::CLI::Command
|
5
|
+
def call(**options)
|
6
|
+
Command.drop
|
7
|
+
Command.create
|
8
|
+
Command.migrate
|
9
|
+
Command.seed
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Hanami::CLI.register 'sequel install', Hanami::Sequel::CLI::Install
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Hanami
|
2
|
+
module Sequel
|
3
|
+
module CLI
|
4
|
+
class Migrate < Hanami::CLI::Command
|
5
|
+
argument :version,
|
6
|
+
required: false,
|
7
|
+
default: 'up',
|
8
|
+
desc: 'Version of the migration (number, offset, timestamp, "up" or "down"). Default: "up"'
|
9
|
+
|
10
|
+
def call(**options)
|
11
|
+
Command.migrate(options)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Command
|
17
|
+
def self.migrate(**options)
|
18
|
+
Hanami::Environment.new # load DATABASE_URL
|
19
|
+
|
20
|
+
args = {}
|
21
|
+
|
22
|
+
if (v = options[:version])
|
23
|
+
case
|
24
|
+
when v == 'up' then;
|
25
|
+
when v == 'down' then args[:target] = 0
|
26
|
+
else args[:target] = Integer(v)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'sequel'
|
31
|
+
::Sequel.extension :migration
|
32
|
+
|
33
|
+
db = ::Sequel.connect(ENV.fetch('DATABASE_URL'),
|
34
|
+
loggers: Logger.new($stdout))
|
35
|
+
|
36
|
+
::Sequel::Migrator.run(db, CLI.config.migrations, **args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Hanami::CLI.register 'sequel migrate', Hanami::Sequel::CLI::Migrate
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module Sequel
|
5
|
+
module CLI
|
6
|
+
class Migration < Hanami::CLI::Command
|
7
|
+
argument :name, required: true, desc: 'Name of the migration'
|
8
|
+
|
9
|
+
def call(name:, **options)
|
10
|
+
now = Time.now.strftime('%Y%m%d%H%M%S')
|
11
|
+
name = Utils::String.underscore(name)
|
12
|
+
destination = File.join('./',
|
13
|
+
CLI.config.migrations,
|
14
|
+
"#{now}_#{name}.rb")
|
15
|
+
|
16
|
+
CLI.generate(CLI.template('migration'), nil, destination)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Hanami::CLI.register 'sequel migration', Hanami::Sequel::CLI::Migration
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module Sequel
|
5
|
+
module CLI
|
6
|
+
class Model < Hanami::CLI::Command
|
7
|
+
argument :name, required: true, desc: 'Name of the model'
|
8
|
+
|
9
|
+
def call(name:, **options)
|
10
|
+
under_name = Utils::String.underscore(name)
|
11
|
+
table_name = Utils::String.pluralize(under_name)
|
12
|
+
|
13
|
+
camel_name = Utils::String.classify(name)
|
14
|
+
model_name = "#{camel_name}Model"
|
15
|
+
|
16
|
+
b = ErBinding.new(model_name: model_name,
|
17
|
+
table_name: table_name)
|
18
|
+
|
19
|
+
# db/migrations/date-create-table_name.rb
|
20
|
+
|
21
|
+
now = Time.now.strftime('%Y%m%d%H%M%S')
|
22
|
+
destination = File.join(CLI.config.migrations,
|
23
|
+
"#{now}_create_#{table_name}.rb")
|
24
|
+
|
25
|
+
CLI.generate(CLI.template('model-migration'), b, destination)
|
26
|
+
|
27
|
+
# lib/project_name/models/model_name.rb
|
28
|
+
|
29
|
+
destination = File.join(CLI.lib_path,
|
30
|
+
'models',
|
31
|
+
"/#{under_name}_model.rb")
|
32
|
+
|
33
|
+
CLI.generate(CLI.template('model-sequel'), b, destination)
|
34
|
+
|
35
|
+
# spec/project_name/models/model_name_spec.rb
|
36
|
+
|
37
|
+
destination = File.join(CLI.spec_path,
|
38
|
+
'models',
|
39
|
+
"/#{under_name}_model_spec.rb")
|
40
|
+
|
41
|
+
CLI.generate(CLI.template('model-spec'), b, destination)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Hanami::CLI.register 'sequel model', Hanami::Sequel::CLI::Model
|