miguel 0.1.0.pre1 → 0.1.0.pre2

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
  SHA1:
3
- metadata.gz: 1c7f6a7a9e366374d9d88b5c5dde5e3ca0e8e9fa
4
- data.tar.gz: 99bc1f4cb8a9ab1bc6f84b8595f541d5226b6f0c
3
+ metadata.gz: 6cc20233657ee51f12faa39ae0c81c55184b09cb
4
+ data.tar.gz: 983d7e268d3cd5f9448b128b56f84f5a2f64cdea
5
5
  SHA512:
6
- metadata.gz: 3e1d62b3872b4961a7df1276cf82ec89829b81d05560ce3d435d48f9a077bc60e46a919a4b21ae7131e24c01ceb521ebd176120525a01ff7f8d989be66335835
7
- data.tar.gz: 483d87a4bd5c54251dce7255e99e54238ddcc6a729d820c881fe841153732854b55b697895b0749d3cd6a07533ea237a43c66abb40dd6b0b4678436f4324908e
6
+ metadata.gz: 61288b386f01bf54e2fedda5f0988e70ab0aaf3eb2133279b43ebc69f277a7cff39c57170eb92c5209fd418dd0a1613ef9ef43a87d75f2d6112ebbcfa96c8b66
7
+ data.tar.gz: 43f256c47f62d61d58f2031d5ec0cbcf6c8d1ce89c0e583e272c7701d9e618e8d51590010412ba4fb37bfca506c49e08f625ac15004ae6541f58f2d7d2107bfe
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  *~
2
+ /miguel-*.gem
data/.travis.gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # Gemfile for TravisCI integration.
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'rake'
6
+ gem 'bacon', '~> 1.2'
7
+ gem 'sequel', '~> 4.0'
8
+
9
+ # EOF #
data/.travis.yml ADDED
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ rvm:
3
+ - ruby-head
4
+ - 2.2.3
5
+ - 2.1.7
6
+ - 2.0.0
7
+ - 1.9.3
8
+ - rbx-2
9
+ - jruby-head
10
+ - jruby-19mode
11
+ gemfile: .travis.gemfile
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: ruby-head
15
+ - rvm: jruby-19mode
16
+ - rvm: jruby-head
data/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # Miguel
2
+
3
+ [![Gem Version](https://img.shields.io/gem/v/miguel.svg)](http://rubygems.org/gems/miguel) [![Build Status](https://img.shields.io/travis/raxoft/miguel.svg?branch=master)](http://travis-ci.org/raxoft/miguel) [![Dependency Status](https://img.shields.io/gemnasium/raxoft/miguel.svg)](https://gemnasium.com/raxoft/miguel) [![Code Climate](https://img.shields.io/codeclimate/github/raxoft/miguel.svg)](https://codeclimate.com/github/raxoft/miguel) [![Coverage](https://img.shields.io/codeclimate/coverage/github/raxoft/miguel.svg)](https://codeclimate.com/github/raxoft/miguel)
4
+
5
+ Miguel is a tool for sane management of database schemas. It aims to help with these goals:
6
+
7
+ * Have just one up-to-date description of the desired database schema using a concise DSL.
8
+ * Apply that schema to the database anytime, no matter how either may have diverged.
9
+ * Adjust and repeat as often as needed.
10
+
11
+ To achieve this, it provides the following features:
12
+
13
+ * [Sequel](http://sequel.jeremyevans.net/)-like DSL for schema description with some enhancements.
14
+ * Load schema from given description file or from given database.
15
+ * Show changes necessary to turn one schema into another.
16
+ * Render those changes as Sequel's change or up/down migrations.
17
+ * Alternatively apply those changes directly to the database.
18
+
19
+ ## Describing the schema
20
+
21
+ The schema is described using a DSL similar to Sequel's
22
+ [standard schema syntax](http://sequel.jeremyevans.net/rdoc/files/doc/schema_modification_rdoc.html).
23
+ It looks like this:
24
+
25
+ ``` ruby
26
+ # Example schema for Miguel.
27
+ Miguel::Schema.define do
28
+
29
+ # The user, the core of every web site.
30
+
31
+ table :users do
32
+ primary_key :id
33
+
34
+ # The login id, usually user email address.
35
+ String :login
36
+ # The encrypted password.
37
+ String :password
38
+
39
+ # First name(s).
40
+ String :first_name
41
+ # Last name(s).
42
+ String :last_name
43
+
44
+ # Arbitrary JSON encoded info.
45
+ Text? :info
46
+
47
+ timestamps
48
+
49
+ unique :login
50
+ index :first_name
51
+ index :last_name
52
+ index :create_time
53
+ end
54
+
55
+ # User's emails, as every user can have multiple emails.
56
+
57
+ table :user_emails do
58
+ primary_key :id
59
+
60
+ # The email address itself.
61
+ String :email
62
+ # To which user does the email belong.
63
+ foreign_key :user_id, :users
64
+
65
+ # Flag set when this email is verified.
66
+ False :verified
67
+ # Flag set when this email is marked as their primary email by the user.
68
+ False :primary
69
+
70
+ timestamps
71
+
72
+ unique :email
73
+ index :user_id
74
+ index :create_time
75
+ end
76
+
77
+ # User's profile, collecting various info about the user.
78
+
79
+ table :user_profiles do
80
+ primary_key :user_id
81
+ foreign_key [:user_id], :users
82
+
83
+ String? :company
84
+ String? :street
85
+ String? :city
86
+ String? :state
87
+ String? :country
88
+ String? :zip
89
+ String? :phone
90
+ String? :fax
91
+ String? :url
92
+
93
+ index :country
94
+ index :state
95
+ end
96
+
97
+ # User's followers.
98
+
99
+ join_table :user_id, :users, :follower_id, :users, :user_followers
100
+
101
+ end
102
+ ```
103
+
104
+ One enhancement is that it allows you to define `NULL` columns simply by adding `?` to the type name.
105
+ Anything else is implicitly `NOT NULL`, which is a really wise default.
106
+
107
+ Another enhancement is that it allows you to set defaults and
108
+ define custom shortcuts for types which you use frequently.
109
+ See documentation of the `set_defaults` method for details.
110
+ The preset defaults are like this:
111
+
112
+ ``` ruby
113
+ set_defaults :global, :null => false
114
+ set_defaults :primary_key, :type => :integer, :unsigned => true
115
+ set_defaults :foreign_key, :key => :id, :type => :integer, :unsigned => true
116
+ set_defaults :unique, :index, :unique => true
117
+ set_defaults :Bool, :TrueClass
118
+ set_defaults :True, :TrueClass, :default => true
119
+ set_defaults :False, :TrueClass, :default => false
120
+ set_defaults :Signed, :integer, :unsigned => false
121
+ set_defaults :Unsigned, :integer, :unsigned => true
122
+ set_defaults :Text, :String, :text => true
123
+ set_defaults :Time, :timestamp, :default => 0
124
+ set_defaults :Time?, :timestamp, :default => nil
125
+ ```
126
+
127
+ Finally, the `timestamp` helper can be used to create the
128
+ `create_time` and `update_time` timestamps for you.
129
+
130
+ ## Using the command
131
+
132
+ Using the command should be pretty straightforward.
133
+ Try `miguel -h` and follow the examples.
134
+ You can basically:
135
+
136
+ * `show` - show schema loaded from given `.rb` file or from given database.
137
+ * `dump` - dump migration which creates such schema.
138
+ * `down` - dump migration which reverses given schema entirely.
139
+ * `diff` - dump migration for migrating from one schema to another.
140
+ * `apply` - apply given schema to given database.
141
+ * `clear` - entirely wipe out schema of given database.
142
+
143
+ You don't have to worry about changing things accidentally,
144
+ the command will always ask for a confirmation before changing anything in the database
145
+ (unless you use the `--force` option).
146
+
147
+ Databases can be specified either by their Sequel URL like
148
+ `mysql2://user:password@localhost/main`,
149
+ or by the common database `.yml` config file:
150
+
151
+ ``` yaml
152
+ adapter: mysql2
153
+ user: jim
154
+ password: sup3rsecr3t
155
+ host: localhost
156
+ database: main
157
+ encoding: utf8
158
+ ```
159
+
160
+ Note that you can use the `--env` option to specify an environment other than `development`
161
+ if your `.yml` contains configs for multiple environments.
162
+
163
+ Use the `--migration <format>` option to choose how you want the migration displayed.
164
+ The `bare` format (the default) shows just the changes themselves,
165
+ the `change` format creates the one-way Sequel's change migration,
166
+ relying on Sequel's ability to reverse it,
167
+ while
168
+ the `full` format creates the two-way Sequel's up/down migration.
169
+
170
+ It's up to you if you will use `diff` each time to create the migration files for you,
171
+ amend them if needed,
172
+ and then let the `sequel` command use them normally,
173
+ or if you will just `apply` the schema directly
174
+ and rely on your VCS to keep its previous versions for you,
175
+ leaving dozens of piecewise migration files finally behind.
176
+
177
+ ## Limitations
178
+
179
+ The type support is geared towards the MySQL, especially the timestamp types.
180
+ Generic types should work with any database, but your mileage may vary.
181
+
182
+ It is currently not possible to describe renaming of columns.
183
+ If you need that,
184
+ simply rename the columns directly in the database or by using standard Sequel migration,
185
+ and adjust the schema description accordingly.
186
+
187
+ ## Credits
188
+
189
+ Copyright &copy; 2015 Patrik Rak
190
+
191
+ Miguel is released under the MIT license.
data/TODO CHANGED
@@ -1,2 +1 @@
1
1
  add tests
2
- write docs
data/examples/db.yml ADDED
@@ -0,0 +1,21 @@
1
+ # Example database configuration.
2
+
3
+ # Development database.
4
+ :development:
5
+ :adapter: mysql2
6
+ :user: dev
7
+ :password: hax0rz
8
+ :host: localhost
9
+ :database: test
10
+ :encoding: utf8
11
+
12
+ # Production database.
13
+ :production:
14
+ :adapter: mysql2
15
+ :user: web
16
+ :password: aGhiTheig6iex6shieMohz5orsomethinglikethat
17
+ :host: localhost
18
+ :database: main
19
+ :encoding: utf8
20
+
21
+ # EOF #
@@ -0,0 +1,133 @@
1
+ # Example schema for Miguel.
2
+ #
3
+ # Few words on indexes/indices, applying to Sequel migrations in general:
4
+ #
5
+ # Create explicit indexes even for foreign keys, to make them named the Sequel way.
6
+ # This also prevents MySQL from using combined index starting with that column for the foreign key.
7
+ # Such combined index couldn't be dropped later because of the foreign key constraint,
8
+ # at least until you would create an explicit one for that single column.
9
+ #
10
+ # Do not create overly complicated indexes before performance proves you really need them.
11
+ # Remember that every index increases insertion time considerably and takes space,
12
+ # so you should always start only with the basic indexes for the fields you need.
13
+
14
+ Miguel::Schema.define do
15
+
16
+ set_standard_defaults
17
+
18
+ # The user, the core of every web site.
19
+
20
+ table :users do
21
+ primary_key :id
22
+
23
+ # The login id, usually user email address.
24
+ String :login
25
+ # The encrypted password.
26
+ String :password
27
+
28
+ # Random bytes associated with this user, used in hashing and encrypting user specific things.
29
+ String :secret
30
+
31
+ # First name(s).
32
+ String :first_name
33
+ # Last name(s).
34
+ String :last_name
35
+
36
+ # String describing which permissions and what access rights the user has, separated by comma.
37
+ Text :permissions
38
+
39
+ # Arbitrary JSON encoded info.
40
+ Text? :info
41
+
42
+ timestamps
43
+
44
+ unique :login
45
+ index :first_name
46
+ index :last_name
47
+ index :create_time
48
+ end
49
+
50
+ # User's emails, as every user can have multiple emails.
51
+
52
+ table :user_emails do
53
+ primary_key :id
54
+
55
+ # The email address itself.
56
+ String :email
57
+ # To which user does the email belong.
58
+ foreign_key :user_id, :users
59
+
60
+ # Flag set when this email is verified.
61
+ False :verified
62
+ # Flag set when this email is marked as their primary email by the user.
63
+ False :primary
64
+
65
+ timestamps
66
+
67
+ unique :email
68
+ index :user_id
69
+ index :create_time
70
+ end
71
+
72
+ # User's profile, collecting various info about the user.
73
+
74
+ table :user_profiles do
75
+ primary_key :user_id
76
+ foreign_key [:user_id], :users
77
+
78
+ String? :company
79
+ String? :street
80
+ String? :city
81
+ String? :state
82
+ String? :country
83
+ String? :zip
84
+ String? :phone
85
+ String? :fax
86
+ String? :url
87
+
88
+ index :country
89
+ index :state
90
+ end
91
+
92
+ # Event log, for recording various things which happen on this web site.
93
+ # Every event contains what kind of object it refers to, what action was taken,
94
+ # what object was involved, if any, and arbitrary additional info stored as JSON.
95
+
96
+ table :events do
97
+ primary_key :id
98
+
99
+ # The kind of the object affected (like user or email)
100
+ String :kind
101
+ # What action was taken (like create or update)
102
+ String :action
103
+
104
+ # Id of the user the event relates to, if any.
105
+ foreign_key? :user_id, :users
106
+ # Id of the user responsible for creating the event, if any.
107
+ foreign_key? :author_id, :users
108
+ # Id of the object involved, whatever it is, for easier database lookup.
109
+ Unsigned? :subject_id
110
+
111
+ # IP of the request, if any.
112
+ String? :ip
113
+
114
+ # Arbitrary JSON encoded info.
115
+ Text :info
116
+
117
+ timestamps
118
+
119
+ index [ :kind, :action ]
120
+ index :user_id
121
+ index :author_id
122
+ index :subject_id
123
+ index :ip
124
+ index :create_time
125
+ end
126
+
127
+ # User's followers.
128
+
129
+ join_table :user_id, :user, :follower_id, :user, :user_followers
130
+
131
+ end
132
+
133
+ # EOF #
data/miguel.gemspec CHANGED
@@ -4,11 +4,11 @@ require File.expand_path( '../lib/miguel/version', __FILE__ )
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'miguel'
7
- s.version = Miguel::VERSION + '.pre1'
7
+ s.version = Miguel::VERSION + '.pre2'
8
8
  s.summary = 'Database migrator and migration generator for Sequel.'
9
9
  s.description = <<EOT
10
10
  This gem makes it easy to create and maintain an up-to-date database schema
11
- and apply it to the database as needed by the means of standard Sequel migrations."
11
+ and apply it to the database as needed by the means of standard Sequel migrations.
12
12
  EOT
13
13
 
14
14
  s.author = 'Patrik Rak'
@@ -19,6 +19,7 @@ EOT
19
19
  s.files = `git ls-files`.split( "\n" )
20
20
  s.executables = `git ls-files -- bin/*`.split( "\n" ).map{ |f| File.basename( f ) }
21
21
 
22
+ s.required_ruby_version = '>= 1.9.3'
22
23
  s.add_runtime_dependency 'sequel', '~> 4.0'
23
24
  s.add_development_dependency 'bacon', '~> 1.2'
24
25
  end
data/test/test_dumper.rb CHANGED
@@ -12,7 +12,7 @@ describe Miguel::Dumper do
12
12
  d << "d"
13
13
  d.text.should == "a\nb\nc\nd\n"
14
14
  end
15
-
15
+
16
16
  should 'support nesting' do
17
17
  d = Miguel::Dumper.new
18
18
  d.dump "test" do
@@ -36,7 +36,7 @@ test do
36
36
  end
37
37
  EOT
38
38
  end
39
-
39
+
40
40
  should 'support text interpolation' do
41
41
  d = Miguel::Dumper.new
42
42
  d << "abc"
@@ -44,7 +44,7 @@ EOT
44
44
  d.text.should == d.to_s
45
45
  d.text.should == "#{d}"
46
46
  end
47
-
47
+
48
48
  should 'accept nonstring arguments' do
49
49
  d = Miguel::Dumper.new
50
50
  d << 123
@@ -52,14 +52,14 @@ EOT
52
52
  d << :test
53
53
  d.text.should == "123\n0.5\ntest\n"
54
54
  end
55
-
55
+
56
56
  should 'support chaining' do
57
57
  d = Miguel::Dumper.new
58
58
  d.dump( "x" ).should == d
59
59
  ( d << "y" << "z" ).should == d
60
60
  d.text.should == "x\ny\nz\n"
61
61
  end
62
-
62
+
63
63
  should 'support custom buffer' do
64
64
  a = []
65
65
  d = Miguel::Dumper.new( a )
@@ -68,7 +68,7 @@ EOT
68
68
  a.should == [ "xyz\n", "abc\n" ]
69
69
  d.text.should == "xyz\nabc\n"
70
70
  end
71
-
71
+
72
72
  should 'support configurable indentation' do
73
73
  d = Miguel::Dumper.new( [], 4 )
74
74
  d.dump "a" do
@@ -84,7 +84,7 @@ a do
84
84
  end
85
85
  EOT
86
86
  end
87
-
87
+
88
88
  end
89
89
 
90
90
  # EOF #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miguel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre1
4
+ version: 0.1.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Rak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-15 00:00:00.000000000 Z
11
+ date: 2015-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -40,7 +40,7 @@ dependencies:
40
40
  version: '1.2'
41
41
  description: |
42
42
  This gem makes it easy to create and maintain an up-to-date database schema
43
- and apply it to the database as needed by the means of standard Sequel migrations."
43
+ and apply it to the database as needed by the means of standard Sequel migrations.
44
44
  email: patrik@raxoft.cz
45
45
  executables:
46
46
  - miguel
@@ -48,9 +48,14 @@ extensions: []
48
48
  extra_rdoc_files: []
49
49
  files:
50
50
  - ".gitignore"
51
+ - ".travis.gemfile"
52
+ - ".travis.yml"
53
+ - README.md
51
54
  - Rakefile
52
55
  - TODO
53
56
  - bin/miguel
57
+ - examples/db.yml
58
+ - examples/schema.rb
54
59
  - lib/miguel.rb
55
60
  - lib/miguel/command.rb
56
61
  - lib/miguel/dumper.rb
@@ -72,7 +77,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
77
  requirements:
73
78
  - - ">="
74
79
  - !ruby/object:Gem::Version
75
- version: '0'
80
+ version: 1.9.3
76
81
  required_rubygems_version: !ruby/object:Gem::Requirement
77
82
  requirements:
78
83
  - - ">"