sqlserver-schema-reflector 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []