definite 0.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.
- data/.gitignore +6 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/README.md +46 -0
- data/Rakefile +1 -0
- data/bin/definite +4 -0
- data/definite.gemspec +28 -0
- data/features/read_definitions.feature +17 -0
- data/features/step_definitions/table_steps.rb +7 -0
- data/features/support/setup.rb +2 -0
- data/lib/definite/cli.rb +12 -0
- data/lib/definite/model/table_definition.rb +32 -0
- data/lib/definite/reader.rb +7 -0
- data/lib/definite/version.rb +3 -0
- data/lib/definite.rb +15 -0
- data/notes.txt +1 -0
- data/spec/definite_spec.rb +7 -0
- data/spec/table_definition_spec.rb +10 -0
- data/spec/test_data/tables/users.table +8 -0
- metadata +152 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.2-p0@dbscript
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Definitive
|
2
|
+
|
3
|
+
Definitive takes a textual description of database tables and updates your database to match.
|
4
|
+
|
5
|
+
## Motivation
|
6
|
+
|
7
|
+
When maintaining a large Rails project, with new features being added on multiple branches, standard ActiveRecord migrations can get in the way; switching branches with uncommitted migrations can leave you in a state where you can't run rake db:migrate or rake db:rollback or any similar commands.
|
8
|
+
|
9
|
+
Definitive overcomes this limitation by taking a different approach. Now you only need to define what your database should look like; focus on the end-goal, rather than the migration. When you run Definitive, it will compare your database with your description of the database, and do the migrations automatically for you.
|
10
|
+
|
11
|
+
## Is it safe?
|
12
|
+
|
13
|
+
Until we reach v1.0.0 you should consider this as experimental, and should understand that using this Gem might cause data-loss. It might drop tables, and do other destructive work. Please be careful.
|
14
|
+
|
15
|
+
Once we reach v1.0.0, it's hoped that it will be safe
|
16
|
+
|
17
|
+
## User guide
|
18
|
+
|
19
|
+
### Description files
|
20
|
+
|
21
|
+
Within a standard Rails project, the description files should be placed in a `db/tables` folder, within `RAILS_ROOT`.
|
22
|
+
|
23
|
+
You can arrange your files as you like, but the best approach is to have one file per database table, named `table_name.table`
|
24
|
+
|
25
|
+
An example table definition looks like this:
|
26
|
+
|
27
|
+
TableDefinition.define :users do
|
28
|
+
|
29
|
+
column :username, :string, :default => nil
|
30
|
+
column :password, :string
|
31
|
+
|
32
|
+
columns :timestamps
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
The call to `TableDefinition.define` starts the definition. The single argument is the name of the table, which can be a string or a symbol. The block passed in should consist of `column` statements, which are broadly similar to an `add_column` call within an ActiveRecord migration.
|
37
|
+
|
38
|
+
### Running Definitive
|
39
|
+
|
40
|
+
The `definitive` executable takes a number of arguments:
|
41
|
+
|
42
|
+
- *definitive read filename* - Reads the filename table definition to check that it is a valid file. This operation does not change your database at all.
|
43
|
+
|
44
|
+
- *definitive read filepath* - Reads the all the `.table` files in the filepath, recursively. Directory structure does not imply a namespace. Files are checked for validity. This operation does not change your database at all.
|
45
|
+
|
46
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/definite
ADDED
data/definite.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "definite/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "definite"
|
7
|
+
s.version = Definite::VERSION
|
8
|
+
s.authors = ["Graham S Savage"]
|
9
|
+
s.email = ["grahamsavage@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/gsavage/definitive"
|
11
|
+
s.summary = %q{Database manipulation without migrations}
|
12
|
+
s.description = %q{Create the definitive description of your DB and let Definitive modify your schema safely for you}
|
13
|
+
|
14
|
+
s.rubyforge_project = "definite"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "cucumber"
|
24
|
+
s.add_development_dependency "aruba"
|
25
|
+
|
26
|
+
s.add_dependency "activerecord"
|
27
|
+
s.add_dependency "thor"
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: Read definitions
|
2
|
+
In order to know what the database should look like
|
3
|
+
As a CLI
|
4
|
+
I want to read definition files
|
5
|
+
|
6
|
+
Scenario: Reading a file
|
7
|
+
Given a file named "users.table" with:
|
8
|
+
"""
|
9
|
+
TableDefinition.define :users do
|
10
|
+
column :username, :string
|
11
|
+
end
|
12
|
+
"""
|
13
|
+
When I run `definite read users.table`
|
14
|
+
Then the output should contain "users"
|
15
|
+
And the output should contain "username"
|
16
|
+
|
17
|
+
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Then /^I should have a table definition for "([^"]*)"$/ do |table_name|
|
2
|
+
TableDefinition.definition(table_name).should_not be_nil
|
3
|
+
end
|
4
|
+
|
5
|
+
Then /^the "([^"]*)" table definition should include a "([^"]*)" column$/ do |table_name, column|
|
6
|
+
TableDefinition[table_name].column_names.should include(column_name)
|
7
|
+
end
|
data/lib/definite/cli.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'definite'
|
3
|
+
module Definite
|
4
|
+
class CLI < Thor
|
5
|
+
|
6
|
+
desc "read FILE or DIRECTORY", "Reads one or more definition files, to check syntax"
|
7
|
+
def read file_or_directories
|
8
|
+
Definite::Reader.read file_or_directories
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class TableDefinition
|
2
|
+
|
3
|
+
def self.definition(table_name)
|
4
|
+
tables[table_name]
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.tables
|
8
|
+
@@tables ||= {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.define(table_name, options={}, &block)
|
12
|
+
puts "Found definition for table #{table_name}"
|
13
|
+
|
14
|
+
@table = TableDefinition.new(table_name.to_s)
|
15
|
+
@table.instance_eval(&block)
|
16
|
+
|
17
|
+
tables[table_name.to_s] = @table
|
18
|
+
end
|
19
|
+
|
20
|
+
def all
|
21
|
+
tables.values
|
22
|
+
end
|
23
|
+
|
24
|
+
def column column_name, datatype, options={}
|
25
|
+
puts "column #{column_name}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def columns column_names
|
29
|
+
puts "columns #{column_names}"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/lib/definite.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "definite/version"
|
2
|
+
require "definite/reader"
|
3
|
+
require "definite/model/table_definition"
|
4
|
+
|
5
|
+
module Definite
|
6
|
+
# Your code goes here...
|
7
|
+
|
8
|
+
def update
|
9
|
+
target_schema = Definite::Reader.read
|
10
|
+
current_schema = Definite::Dumper.read
|
11
|
+
changes = Definite::Changes.difference :new_schema => new_schema, :current_schema => current_schema
|
12
|
+
Definite::Writer.write changes
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/notes.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Schema dump uses ActiveRecord::SchemaDumper
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: definite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Graham S Savage
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-10-24 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :development
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: cucumber
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :development
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: aruba
|
48
|
+
prerelease: false
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id003
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: activerecord
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
type: :runtime
|
71
|
+
version_requirements: *id004
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: thor
|
74
|
+
prerelease: false
|
75
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
type: :runtime
|
84
|
+
version_requirements: *id005
|
85
|
+
description: Create the definitive description of your DB and let Definitive modify your schema safely for you
|
86
|
+
email:
|
87
|
+
- grahamsavage@gmail.com
|
88
|
+
executables:
|
89
|
+
- definite
|
90
|
+
extensions: []
|
91
|
+
|
92
|
+
extra_rdoc_files: []
|
93
|
+
|
94
|
+
files:
|
95
|
+
- .gitignore
|
96
|
+
- .rvmrc
|
97
|
+
- Gemfile
|
98
|
+
- README.md
|
99
|
+
- Rakefile
|
100
|
+
- bin/definite
|
101
|
+
- definite.gemspec
|
102
|
+
- features/read_definitions.feature
|
103
|
+
- features/step_definitions/table_steps.rb
|
104
|
+
- features/support/setup.rb
|
105
|
+
- lib/definite.rb
|
106
|
+
- lib/definite/cli.rb
|
107
|
+
- lib/definite/model/table_definition.rb
|
108
|
+
- lib/definite/reader.rb
|
109
|
+
- lib/definite/version.rb
|
110
|
+
- notes.txt
|
111
|
+
- spec/definite_spec.rb
|
112
|
+
- spec/table_definition_spec.rb
|
113
|
+
- spec/test_data/tables/users.table
|
114
|
+
has_rdoc: true
|
115
|
+
homepage: https://github.com/gsavage/definitive
|
116
|
+
licenses: []
|
117
|
+
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
segments:
|
129
|
+
- 0
|
130
|
+
version: "0"
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
version: "0"
|
139
|
+
requirements: []
|
140
|
+
|
141
|
+
rubyforge_project: definite
|
142
|
+
rubygems_version: 1.3.7
|
143
|
+
signing_key:
|
144
|
+
specification_version: 3
|
145
|
+
summary: Database manipulation without migrations
|
146
|
+
test_files:
|
147
|
+
- features/read_definitions.feature
|
148
|
+
- features/step_definitions/table_steps.rb
|
149
|
+
- features/support/setup.rb
|
150
|
+
- spec/definite_spec.rb
|
151
|
+
- spec/table_definition_spec.rb
|
152
|
+
- spec/test_data/tables/users.table
|