sqlserver-schema-reflector 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 ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .redcar/
6
+ schema.sql
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+ gem 'json'
3
+ gem 'json_pure'
4
+ gem 'rspec'
5
+ gem 'tiny_tds'
6
+ # Specify your gem's dependencies in sqlserver_schema_reflector.gemspec
7
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'bundler/gem_tasks'
2
+ task :run do
3
+ require './lib/sqlserver_schema_reflector.rb'
4
+ SqlServerSchemaReflector::Reflector.run(
5
+ File.open('./schema.sql', 'w'),
6
+ :username => 'user',
7
+ :password => 'user',
8
+ :host => '16.88.192.55',
9
+ :database => 'todNMCIAOM'
10
+ )
11
+ end
12
+ task :test do
13
+ system 'bundle exec rspec spec/sqlserver_schema_reflector_test.rb'
14
+ end
@@ -0,0 +1,11 @@
1
+ module SqlServerSchemaReflector
2
+ end
3
+ require "sqlserver_schema_reflector/version"
4
+ require 'json'
5
+ require 'tiny_tds'
6
+ require 'sqlserver_schema_reflector/string'
7
+ require 'sqlserver_schema_reflector/hash'
8
+ require 'sqlserver_schema_reflector/array'
9
+ require 'sqlserver_schema_reflector/column_reflection.rb'
10
+ require "sqlserver_schema_reflector/table_reflection.rb"
11
+ require "sqlserver_schema_reflector/reflector.rb"
@@ -0,0 +1,15 @@
1
+ class Array
2
+ def find_hashes(keys)
3
+ results = []
4
+ each do |item|
5
+ hash = item.find_hashes(keys)
6
+ if !hash.nil?
7
+ results.push(hash)
8
+ end
9
+ end
10
+ return nil if results.length == 0
11
+ return results[0] if results.length == 1
12
+ return results
13
+ end
14
+
15
+ end
@@ -0,0 +1,30 @@
1
+ class SqlServerSchemaReflector::ColumnReflection
2
+ attr_reader :identity
3
+ def initialize(properties, identity = nil)
4
+ @properties = properties
5
+ if identity[:identity] === properties[:column_name]
6
+ @identity = identity unless identity.nil?
7
+ end
8
+ end
9
+ def name
10
+ @properties[:column_name]
11
+ end
12
+ def type
13
+ @properties[:type]
14
+ end
15
+ def length
16
+ "(#{@properties[:length]})" unless @properties[:length].nil? || type === 'int'
17
+ end
18
+ def nullable
19
+ _nullable = "NOT NULL"
20
+ _nullable = "NULL" if @properties[:nullable] === 'yes'
21
+ _nullable
22
+ end
23
+ def id_statement
24
+ "IDENTITY(#{@identity[:seed]},#{@identity[:increment]})" unless @identity.nil?
25
+ end
26
+ def sql
27
+ "[#{name}] [#{type}]#{length} #{id_statement} #{nullable}"
28
+ end
29
+
30
+ end
@@ -0,0 +1,15 @@
1
+ class Hash
2
+ def symbolize_keys
3
+ inject({}) do |options, (key, value)|
4
+ options[(key.underscore.downcase.to_sym rescue key) || key] = value
5
+ options
6
+ end
7
+ end
8
+ def find_hashes(keys)
9
+ h = symbolize_keys
10
+ keys.each do |k|
11
+ return nil unless h.keys.include? k
12
+ end
13
+ return h
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ class SqlServerSchemaReflector::Reflector
2
+ def self.run(out, options)
3
+ client = TinyTds::Client.new(options)
4
+ names = client.execute("SELECT ([TABLE_SCHEMA] + '.' + [TABLE_NAME]) AS name FROM information_schema.tables").map {|r| r['name']}
5
+ names.each do |name|
6
+ begin
7
+ table_hash = client.execute("sp_help '#{name}'").map { |result| result }
8
+ table = SqlServerSchemaReflector::TableReflection.new(table_hash)
9
+ out.write table.create_sql + "\n"
10
+ puts "Successfully generated create statement for #{name}"
11
+ rescue
12
+ e = "/*\n"
13
+ e << "Unable to generate create statement for table: #{name}\n"
14
+ e << $!
15
+ e << "*/\n"
16
+ out.write e
17
+ $stderr.print e
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,10 @@
1
+ class String
2
+ def underscore
3
+ self.gsub(/::/, '/').
4
+ gsub(' ', '_').
5
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
6
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
7
+ tr("-", "_").
8
+ downcase
9
+ end
10
+ end
@@ -0,0 +1,48 @@
1
+ class SqlServerSchemaReflector::TableReflection
2
+ def initialize(properties)
3
+ @properties = properties
4
+ end
5
+ def meta
6
+ @meta ||= @properties.find_hashes [:name, :owner, :type]
7
+ end
8
+ def columns
9
+ if @columns.nil?
10
+ @columns = []
11
+ column_hashes = @properties.find_hashes [:column_name, :type]
12
+ column_hashes = [column_hashes] if column_hashes.class.name == 'Hash'
13
+ column_hashes.each do |column|
14
+ @columns.push(SqlServerSchemaReflector::ColumnReflection.new(column, identity))
15
+ end
16
+ end
17
+ @columns
18
+ end
19
+ def identity
20
+ if @identity.nil?
21
+ @identity = @properties.find_hashes [:identity, :seed, :increment]
22
+ @identity[:seed] = @identity[:seed].to_f.to_i
23
+ @identity[:increment] = @identity[:increment].to_f.to_i
24
+ end
25
+ @identity
26
+ end
27
+ def indexes
28
+ if @indexes.nil?
29
+ @indexes = @properties.find_hashes [:index_name, :index_description, :index_keys]
30
+ @indexes = [@indexes] if @indexes.class.name === 'Hash'
31
+ end
32
+ @indexes
33
+ end
34
+ def constraints
35
+ if @constraints.nil?
36
+ @constraints = @properties.find_hashes [:constraint_name, :constraint_type]
37
+ @constraints = [@constraints] if @constraints.class.name === 'Hash'
38
+ end
39
+ @constraints
40
+ end
41
+ def create_sql
42
+ sql = "CREATE TABLE [#{meta[:owner]}].[#{meta[:name]}]("
43
+ columns.each do |c|
44
+ sql << "\n\t#{c.sql},"
45
+ end
46
+ sql << "\n)"
47
+ end
48
+ end
@@ -0,0 +1,3 @@
1
+ module SqlserverSchemaReflector
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,91 @@
1
+ [
2
+ [
3
+ [{"Name":"employees","Owner":"dbo","Type":"user table","Created_datetime":"2011-07-19 14:08:32 -0600"}],
4
+ [
5
+ {
6
+ "Column_name":"id",
7
+ "Type":"int",
8
+ "Computed":"no",
9
+ "Length":4,
10
+ "Prec":"10",
11
+ "Scale":"0",
12
+ "Nullable":"no",
13
+ "TrimTrailingBlanks":"(n/a)",
14
+ "FixedLenNullInSource":"(n/a)",
15
+ "Collation":null
16
+ },
17
+ {
18
+ "Column_name":"first_name",
19
+ "Type":"varchar",
20
+ "Computed":"no",
21
+ "Length":255,
22
+ "Prec":"",
23
+ "Scale":"",
24
+ "Nullable":"yes",
25
+ "TrimTrailingBlanks":"no",
26
+ "FixedLenNullInSource":"yes",
27
+ "Collation":"SQL_Latin1_General_CP1_CI_AS"
28
+ },
29
+ {
30
+ "Column_name":"last_name",
31
+ "Type":"varchar",
32
+ "Computed":"no",
33
+ "Length":255,
34
+ "Prec":"",
35
+ "Scale":"",
36
+ "Nullable":"yes",
37
+ "TrimTrailingBlanks":"no",
38
+ "FixedLenNullInSource":"yes",
39
+ "Collation":"SQL_Latin1_General_CP1_CI_AS"
40
+ },
41
+ {
42
+ "Column_name":"suffix",
43
+ "Type":"varchar",
44
+ "Computed":"no",
45
+ "Length":255,
46
+ "Prec":" ",
47
+ "Scale":" ",
48
+ "Nullable":"yes",
49
+ "TrimTrailingBlanks":"no",
50
+ "FixedLenNullInSource":"yes",
51
+ "Collation":"SQL_Latin1_General_CP1_CI_AS"
52
+ }
53
+ ],
54
+ [
55
+ {
56
+ "Identity":"id",
57
+ "Seed":"0.1E1",
58
+ "Increment":"0.1E1",
59
+ "Not For Replication":0
60
+ }
61
+ ],
62
+ [
63
+ {
64
+ "RowGuidCol":"No rowguidcol column defined."
65
+ }
66
+ ],
67
+ [
68
+ {
69
+ "Data_located_on_filegroup":"PRIMARY"
70
+ }
71
+ ],
72
+ [
73
+ {
74
+ "index_name":"PK__employee__3213E83F023D5A04",
75
+ "index_description":"clustered, unique, primary key located on PRIMARY",
76
+ "index_keys":"id"
77
+ }
78
+ ],
79
+ [
80
+ {
81
+ "constraint_type":"PRIMARY KEY (clustered)",
82
+ "constraint_name":"PK__employee__3213E83F023D5A04",
83
+ "delete_action":"(n/a)",
84
+ "update_action":"(n/a)",
85
+ "status_enabled":"(n/a)",
86
+ "status_for_replication":"(n/a)",
87
+ "constraint_keys":"id"
88
+ }
89
+ ]
90
+ ]
91
+ ]
@@ -0,0 +1,80 @@
1
+ require 'sqlserver_schema_reflector'
2
+
3
+ def employees_table_def
4
+ @employees_table ||= JSON.parse(File.read('./spec/fixtures/object_definitions.json'))[0]
5
+ end
6
+
7
+ def table_reflection
8
+ SqlServerSchemaReflector::TableReflection.new(employees_table_def)
9
+ end
10
+
11
+ def column_reflection
12
+ SqlServerSchemaReflector::ColumnReflection.new(
13
+ employees_table_def.find_hashes([:column_name])[0],
14
+ table_reflection.identity
15
+ )
16
+ end
17
+
18
+ describe SqlServerSchemaReflector do
19
+ describe SqlServerSchemaReflector::TableReflection do
20
+
21
+ describe "#new" do
22
+ it "creates an object with correct meta data" do
23
+ table_reflection.meta.should be_a(Hash)
24
+ table_reflection.meta[:name].should == "employees"
25
+ table_reflection.meta[:owner].should == "dbo"
26
+ table_reflection.meta[:type].should == "user table"
27
+ end
28
+ it "creates an array of column reflection objects" do
29
+ table_reflection.columns.should be_an(Array)
30
+ table_reflection.columns.length.should == 4
31
+ table_reflection.columns[0].should be_a(SqlServerSchemaReflector::ColumnReflection)
32
+ table_reflection.columns[0].name.should == "id"
33
+ table_reflection.columns[0].type.should == 'int'
34
+ end
35
+ it "creates an object with correct identity data" do
36
+ table_reflection.identity[:identity].should === 'id'
37
+ table_reflection.identity[:seed].should === 1
38
+ table_reflection.identity[:increment].should === 1
39
+ table_reflection.identity[:not_for_replication].should == 0
40
+ end
41
+ it "creates an object with correct index data" do
42
+ table_reflection.indexes.length.should === 1
43
+ table_reflection.indexes[0][:index_name].should === 'PK__employee__3213E83F023D5A04'
44
+ table_reflection.indexes[0][:index_description].should === 'clustered, unique, primary key located on PRIMARY'
45
+ table_reflection.indexes[0][:index_keys].should === 'id'
46
+ end
47
+ it "creates an object with correct constraints" do
48
+ table_reflection.constraints.length.should === 1
49
+ table_reflection.constraints[0][:constraint_name].should === "PK__employee__3213E83F023D5A04"
50
+ table_reflection.constraints[0][:constraint_type].should === "PRIMARY KEY (clustered)"
51
+ end
52
+ it "generates proper sql create table statement" do
53
+ table_reflection.create_sql.should === "" <<
54
+ "CREATE TABLE [dbo].[employees](\n" <<
55
+ "\t[id] [int] IDENTITY(1,1) NOT NULL,\n" <<
56
+ "\t[first_name] [varchar](255) NULL,\n" <<
57
+ "\t[last_name] [varchar](255) NULL,\n" <<
58
+ "\t[suffix] [varchar](255) NULL,\n" <<
59
+ ")"
60
+ end
61
+ end
62
+ end
63
+ describe SqlServerSchemaReflector::ColumnReflection do
64
+ it "creates an object with correct properties" do
65
+ column_reflection.name.should == 'id'
66
+ column_reflection.type.should == 'int'
67
+ end
68
+ it "creates an object with proper identity data" do
69
+ column_reflection.identity.should be_a(Hash)
70
+ column_reflection.identity[:seed].should === 1
71
+ column_reflection.identity[:increment].should === 1
72
+ end
73
+ it "creates the proper sql column declaration" do
74
+ table_reflection.columns[0].sql.should === "[id] [int] IDENTITY(1,1) NOT NULL"
75
+ table_reflection.columns[1].sql.should === "[first_name] [varchar](255) NULL"
76
+ table_reflection.columns[2].sql.should === "[last_name] [varchar](255) NULL"
77
+ table_reflection.columns[3].sql.should === '[suffix] [varchar](255) NULL'
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sqlserver_schema_reflector/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "sqlserver-schema-reflector"
7
+ s.version = SqlserverSchemaReflector::VERSION
8
+ s.authors = ["Jacob Morris"]
9
+ s.email = ["jacob.s.morris@gmail.com"]
10
+ s.homepage = "http://www.thewhitespace.co"
11
+ s.summary = %q{Analyze any SqlServer database and produce a sql script for replicating the database}
12
+ s.description = %q{Analyzing any SqlServer database and produce a sql script for replicating the database}
13
+
14
+ s.add_dependency 'json'
15
+ s.add_dependency 'json_pure'
16
+ s.add_dependency 'tiny_tds'
17
+
18
+ s.rubyforge_project = "sqlserver_schema_reflector"
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sqlserver-schema-reflector
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jacob Morris
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-07-21 00:00:00.000000000 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ requirement: &29136084 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *29136084
26
+ - !ruby/object:Gem::Dependency
27
+ name: json_pure
28
+ requirement: &29135832 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *29135832
37
+ - !ruby/object:Gem::Dependency
38
+ name: tiny_tds
39
+ requirement: &29135580 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *29135580
48
+ description: Analyzing any SqlServer database and produce a sql script for replicating
49
+ the database
50
+ email:
51
+ - jacob.s.morris@gmail.com
52
+ executables: []
53
+ extensions: []
54
+ extra_rdoc_files: []
55
+ files:
56
+ - .gitignore
57
+ - Gemfile
58
+ - Rakefile
59
+ - lib/sqlserver_schema_reflector.rb
60
+ - lib/sqlserver_schema_reflector/array.rb
61
+ - lib/sqlserver_schema_reflector/column_reflection.rb
62
+ - lib/sqlserver_schema_reflector/hash.rb
63
+ - lib/sqlserver_schema_reflector/reflector.rb
64
+ - lib/sqlserver_schema_reflector/string.rb
65
+ - lib/sqlserver_schema_reflector/table_reflection.rb
66
+ - lib/sqlserver_schema_reflector/version.rb
67
+ - spec/fixtures/object_definitions.json
68
+ - spec/sqlserver_schema_reflector_test.rb
69
+ - sqlserver_schema_reflector.gemspec
70
+ has_rdoc: true
71
+ homepage: http://www.thewhitespace.co
72
+ licenses: []
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project: sqlserver_schema_reflector
91
+ rubygems_version: 1.5.2
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: Analyze any SqlServer database and produce a sql script for replicating the
95
+ database
96
+ test_files: []