mssql 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ require "ZenTest"
2
+ #require "autotest/rails"
3
+ require "autotest/growl"
4
+ #require 'redgreen/autotest'
5
+ require "autotest/fsevent"
6
+ Autotest.add_hook :initialize do |autotest|
7
+ %w{.git .svn .hg .DS_Store ._* vendor tmp log doc config .rvmrc Gemfile .autotest README Rakefile, paypal_test}.each do |exception|
8
+ autotest.add_exception(exception)
9
+ end
10
+ end
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ Gemfile.lock
@@ -0,0 +1 @@
1
+ 1.9.2-p290
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source :rubygems
2
+ #source "http://gems.minus5.hr"
3
+ # Specify your gem's dependencies in mssql.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem "tiny_tds", "0.5.0"
8
+ gem "hashie", "1.0.0"
9
+ gem "activesupport", "3.1.1"
10
+
11
+ gem 'minitest', '>=2.7.0'
12
+ gem 'ZenTest'
13
+ gem 'autotest-growl'
14
+ gem 'autotest-fsevent'
15
+ end
16
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Igor Anic
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,190 @@
1
+ # mssql
2
+
3
+ Command line tool for connecting to Microsoft Sql Server from Mac or Linux.
4
+
5
+ ## Installation
6
+
7
+ gem install mssql
8
+
9
+ ## Usage
10
+
11
+ Usage: mssql <options>
12
+
13
+ -c, --connection CONNECTION use connection defined in ~/.mssql
14
+ -h, --host HOST server host
15
+ -u, --username USERNAME username
16
+ -p, --password PASSWORD password
17
+ -d, --database DATABASE use database name
18
+ -i, --input_file INPUT_FILE input file name
19
+ -q, --query QUERY run query and exit
20
+ -?, --help show syntax summary
21
+
22
+ Connect to database:
23
+
24
+ $ mssql -h host -u user -p password -d database
25
+
26
+ Use connection from config file (~/.mssql):
27
+
28
+ $ mssql -c alfa
29
+
30
+ Execute query and exit:
31
+
32
+ $ mssql -c alfa -q "select * from authors"
33
+
34
+
35
+ ### Commands
36
+
37
+ Commands are prefixed with dot. Currently recognized commands are:
38
+
39
+ * .find
40
+ * .explain
41
+ * .exit
42
+
43
+ #### query
44
+
45
+ pubs> use pubs
46
+ pubs> select top 5 * from authors
47
+ pubs> go
48
+
49
+ +-------------+----------+----------+--------------+----------------------+------------+-------+-------+----------+
50
+ | au_id | au_lname | au_fname | phone | address | city | state | zip | contract |
51
+ +-------------+----------+----------+--------------+----------------------+------------+-------+-------+----------+
52
+ | 172-32-1176 | White | Johnson | 408 496-7223 | 10932 Bigge Rd. | Menlo Park | CA | 94025 | true |
53
+ | 213-46-8915 | Green | Marjorie | 415 986-7020 | 309 63rd St. #411 | Oakland | CA | 94618 | true |
54
+ | 238-95-7766 | Carson | Cheryl | 415 548-7723 | 589 Darwin Ln. | Berkeley | CA | 94705 | true |
55
+ | 267-41-2394 | O'Leary | Michael | 408 286-2428 | 22 Cleveland Av. #14 | San Jose | CA | 95128 | true |
56
+ | 274-80-9391 | Straight | Dean | 415 834-2919 | 5420 College Av. | Oakland | CA | 94609 | true |
57
+ +-------------+----------+----------+--------------+----------------------+------------+-------+-------+----------+
58
+ 5 rows affected
59
+
60
+ #### .find
61
+
62
+ .find will list all database objects:
63
+
64
+ pubs> .find
65
+ +-----------+--------+--------------------------+
66
+ | type | schema | name |
67
+ +-----------+--------+--------------------------+
68
+ | table | dbo | authors |
69
+ | table | dbo | discounts |
70
+ | table | dbo | employee |
71
+ | table | dbo | jobs |
72
+ | table | dbo | pub_info |
73
+ | table | dbo | publishers |
74
+ | table | dbo | roysched |
75
+ | table | dbo | sales |
76
+ | table | dbo | stores |
77
+ | table | dbo | sysdiagrams |
78
+ | table | dbo | titleauthor |
79
+ | table | dbo | titles |
80
+ | view | dbo | titleview |
81
+ | procedure | dbo | byroyalty |
82
+ | procedure | dbo | reptq1 |
83
+ | procedure | dbo | reptq2 |
84
+ | procedure | dbo | reptq3 |
85
+ | procedure | dbo | sp_alterdiagram |
86
+ | procedure | dbo | sp_creatediagram |
87
+ | procedure | dbo | sp_dropdiagram |
88
+ | procedure | dbo | sp_helpdiagramdefinition |
89
+ | procedure | dbo | sp_helpdiagrams |
90
+ | procedure | dbo | sp_renamediagram |
91
+ | procedure | dbo | sp_upgraddiagrams |
92
+ | function | dbo | fn_diagramobjects |
93
+ +-----------+--------+--------------------------+
94
+ 25 rows affected
95
+
96
+ or objects by type (tables/views/procedures/functions):
97
+
98
+ pubs> .find tables
99
+ +-------+--------+-------------+
100
+ | type | schema | name |
101
+ +-------+--------+-------------+
102
+ | table | dbo | authors |
103
+ | table | dbo | discounts |
104
+ | table | dbo | employee |
105
+ | table | dbo | jobs |
106
+ | table | dbo | pub_info |
107
+ | table | dbo | publishers |
108
+ | table | dbo | roysched |
109
+ | table | dbo | sales |
110
+ | table | dbo | stores |
111
+ | table | dbo | sysdiagrams |
112
+ | table | dbo | titleauthor |
113
+ | table | dbo | titles |
114
+ +-------+--------+-------------+
115
+ 12 rows affected
116
+
117
+
118
+ #### .explain
119
+
120
+ .explain for procedures/functions/views returns sql body, for tables executes sp_help [table name]
121
+
122
+ iow> .explain reptq1
123
+ CREATE PROCEDURE reptq1 AS
124
+ select
125
+ case when grouping(pub_id) = 1 then 'ALL' else pub_id end as pub_id,
126
+ avg(price) as avg_price
127
+ from titles
128
+ where price is NOT NULL
129
+ group by pub_id with rollup
130
+ order by pub_id
131
+
132
+ #### .exit
133
+
134
+ Use it to close mssql.
135
+
136
+ ## Configuration file ~/.mssql
137
+
138
+ Mssql tries to read ~/.mssql config file on start up.
139
+ Config file is in yaml format.
140
+
141
+ Example config file:
142
+
143
+ alfa: &alfa
144
+ name: alfa
145
+ host: alfa_host
146
+ username: my_username
147
+ password: my_password
148
+ database: pubs
149
+ beta:
150
+ name: beta
151
+ host: beta_host
152
+ username: domain\domain_user
153
+ password: password
154
+ database: Northwind
155
+
156
+ default_connection:
157
+ <<: *alfa
158
+
159
+ With config file you can start mssql using -c argument to specify connection:
160
+
161
+ mssql -c alfa
162
+
163
+ If default connection exists it will used if no arguments specified:
164
+
165
+ mssql
166
+ alfa> _
167
+
168
+ ## Emacs usage
169
+
170
+ I build this for use with Emacs sql-mode. Add ./emacs/sql_ms.el to your init.el:
171
+
172
+ (add-to-list 'load-path "~/Work/mssql/emacs/")
173
+ (require 'sql-ms)
174
+
175
+ Create ~/.mssql file with connections you want to use.
176
+ In Emacs press F12 or M-x enter-db-mode to open two buffers: \*queries\* and \*SQL\*. Write your queries in queries buffer and watch results in SQL buffer.
177
+
178
+ Keybindings:
179
+
180
+ * Ctrl-c c - sends region from queries to SQL buffer
181
+ * Ctrl-c b - sends whole buffer
182
+ * Ctrl-c Ctrl-l a - list database objects in new buffer
183
+ * Ctrl-c Ctrl-l t - .explain in new buffer
184
+
185
+ ## Thanks
186
+
187
+ * Ken Collins for creating [tiny_tds](https://github.com/rails-sqlserver/tiny_tds)
188
+ * All the kind people who are contributing to [freetds](http://www.freetds.org/)
189
+ * Michael Mauger and others for developing [sql.el](http://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/sql.el)
190
+
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ task :default => [:test]
6
+ Rake::TestTask.new do |t|
7
+ t.pattern = "test/test_*.rb"
8
+ # test.verbose = true
9
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+ $: << File.join(File.dirname(Pathname.new(__FILE__).realpath), "..")
4
+ require 'lib/mssql'
5
+
6
+ controller = Controller.new
7
+ controller.run
@@ -0,0 +1,120 @@
1
+ (require 'sql)
2
+
3
+ (defcustom sql-conn ""
4
+ "Default mssql connection."
5
+ :type 'string
6
+ :group 'SQL
7
+ :safe 'stringp)
8
+
9
+ ;; customize ms sql mode
10
+ (setq sql-ms-program "mssql.rb")
11
+ (setq sql-ms-options '())
12
+ (setq sql-ms-login-params '(conn))
13
+
14
+ (defun my-sql-comint-ms (product options)
15
+ "Create comint buffer and connect to Microsoft SQL Server."
16
+ ;; Put all parameters to the program (if defined) in a list and call
17
+ ;; make-comint.
18
+ (setq sql-conn
19
+ (sql-get-login-ext "Connection: " sql-conn nil nil)
20
+ )
21
+ (let ((params options))
22
+ (if (not (string= "" sql-conn))
23
+ (setq params (append (list "-c" sql-conn) params)))
24
+ (sql-comint product params)))
25
+
26
+ (sql-set-product-feature 'ms :sqli-comint-func 'my-sql-comint-ms)
27
+
28
+ ;;sql mode hooks
29
+ (add-hook 'sql-mode-hook (lambda ()
30
+ (setq truncate-lines t)
31
+ (sql-highlight-ms-keywords)
32
+ (setq sql-send-terminator t)
33
+ (setq comint-process-echoes t)
34
+ (setq tab-width 2)))
35
+ (add-hook 'sql-interactive-mode-hook (lambda ()
36
+ (setq truncate-lines t)
37
+ (setq comint-process-echoes t)
38
+ (text-scale-decrease 1)))
39
+
40
+ ;; opening sql buffers
41
+ (defvar db-buffer "queries")
42
+ (defsubst db-get-buffer () (concat "*" db-buffer "*"))
43
+
44
+ (defun enter-db-mode ()
45
+ (interactive)
46
+ (sql-ms)
47
+ (delete-other-windows)
48
+ (split-window-horizontally)
49
+ (switch-to-buffer-other-window (db-get-buffer) t)
50
+ (sql-mode)
51
+ ;(sql-highlight-ms-keywords)
52
+ (swap-windows)
53
+ (other-window -1)
54
+ )
55
+
56
+ (global-set-key [f12] 'enter-db-mode)
57
+
58
+ (sql-set-product-feature 'ms :list-all ".find")
59
+ (sql-set-product-feature 'ms :list-table ".explain %s")
60
+ (sql-set-product-feature 'ms :prompt-regexp "^\\w*> ")
61
+ (sql-set-product-feature 'ms :completion-object 'sql-ms-completion-object)
62
+ (sql-set-product-feature 'ms :completion-column 'sql-ms-completion-object)
63
+
64
+ (defun sql-ms-completion-object (sqlbuf schema)
65
+ (sql-redirect-value
66
+ (sql-find-sqli-buffer)
67
+ (concat
68
+ "select s.name + '.' + o.name"
69
+ " from sys.objects o"
70
+ " inner join sys.schemas s on o.schema_id = s.schema_id"
71
+ " where"
72
+ " type in ('P', 'V', 'U', 'TF', 'IF', 'FN' )"
73
+ " and is_ms_shipped = 0"
74
+ "\ngo"
75
+ )
76
+ "^| \\([a-zA-Z0-9_\.]+\\).*|$" 1)
77
+ )
78
+
79
+ ;;fixing a function from sql.el
80
+ (defun sql-try-completion (string collection &optional predicate)
81
+ (when sql-completion-sqlbuf
82
+ (with-current-buffer sql-completion-sqlbuf
83
+ (let ((schema (and (string-match "\\`\\(\\sw\\(:?\\sw\\|\\s_\\)*\\)[.]" string)
84
+ (downcase (match-string 1 string)))))
85
+
86
+ ;; If we haven't loaded any object name yet, load local schema
87
+ (unless sql-completion-object
88
+ (sql-build-completions nil))
89
+
90
+ ;; If they want another schema, load it if we haven't yet
91
+ (when schema
92
+ (let ((schema-dot (concat schema "."))
93
+ (schema-len (1+ (length schema)))
94
+ (names sql-completion-object)
95
+ has-schema)
96
+
97
+ (while (and (not has-schema) names)
98
+ (setq has-schema (and
99
+ (>= (length (car names)) schema-len)
100
+ (string= schema-dot
101
+ (downcase (substring (car names)
102
+ 0 schema-len))))
103
+ names (cdr names)))
104
+ (unless has-schema
105
+ (sql-build-completions schema)))))
106
+
107
+ (cond
108
+ ((not predicate)
109
+ (try-completion string sql-completion-object))
110
+ ((eq predicate t)
111
+ (all-completions string sql-completion-object))
112
+ ((eq predicate 'lambda)
113
+ (test-completion string sql-completion-object))
114
+ ;;ianic added this condition
115
+ ((eq predicate 'metadata)
116
+ (test-completion string sql-completion-object))
117
+ ((eq (car predicate) 'boundaries)
118
+ (completion-boundaries string sql-completion-object nil (cdr predicate)))))))
119
+
120
+ (provide 'sql-ms)
@@ -0,0 +1,133 @@
1
+ class Command
2
+
3
+ def initialize(command, connection)
4
+ @connection = connection
5
+ @command = command.strip.downcase
6
+ @processed = false
7
+ end
8
+
9
+ attr_reader :processed
10
+
11
+ def self.go?(command)
12
+ command.strip.downcase == "go"
13
+ end
14
+
15
+ def go?
16
+ @command == "go" || @command.start_with?(".use")
17
+ end
18
+
19
+ def exit?
20
+ @command == ".exit" || @command == ".quit"
21
+ end
22
+
23
+ def exec
24
+ parse
25
+ @processed || go? || exit?
26
+ end
27
+
28
+ def parse
29
+ cp = CommandParser.new(@command)
30
+ @processed = cp.is_command?
31
+ return unless cp.is_command?
32
+ case cp.command
33
+ when :find
34
+ types = nil
35
+ p = cp.params[0]
36
+ if p
37
+ types = "'U'" if p.start_with?("table")
38
+ types = "'V'" if p.start_with?("view")
39
+ types = "'P'" if p.start_with?("procedure")
40
+ types = "'TF', 'IF', 'FN'" if p.start_with?("function")
41
+ end
42
+ find(types, types.nil? ? cp.params[0].to_s + cp.params[1].to_s : cp.params[1])
43
+ when :explain
44
+ if cp.params[1].nil? || cp.params[1].empty?
45
+ schema = 'dbo'
46
+ object = cp.params[0]
47
+ else
48
+ schema = cp.params[0]
49
+ object = cp.params[1]
50
+ end
51
+ explain_object schema, object
52
+ when :use
53
+ @connection.use cp.params[0]
54
+ end
55
+ end
56
+
57
+ def find(types, name)
58
+ types = "'TF', 'IF', 'FN', 'P', 'V', 'U'" if types.nil?
59
+ sql = <<-EOS
60
+ select
61
+ --db_name() [database],
62
+ case when type in ('TF', 'IF', 'FN') then 'function'
63
+ when type in ('P') then 'procedure'
64
+ when type in ('V') then 'view'
65
+ when type in ('U') then 'table'
66
+ else '???'
67
+ end type,
68
+ s.name [schema],
69
+ o.name
70
+ from sys.objects o
71
+ inner join sys.schemas s on o.schema_id = s.schema_id
72
+ where
73
+ type in ( #{types} )
74
+ and is_ms_shipped = 0
75
+
76
+ and s.name + "." + o.name like '%#{name}%'
77
+ order by
78
+ case when o.schema_id = 1 then 0 else 1 end, --prvo dbo schema
79
+ case when type in ('TF', 'IF', 'FN') then 4
80
+ when type in ('P') then 3
81
+ when type in ('V') then 2
82
+ when type in ('U') then 1
83
+ else 100
84
+ end,
85
+ s.name, o.name
86
+ EOS
87
+ QueryOutput.new(@connection, sql).show
88
+ @processed = true
89
+ end
90
+
91
+ def show_tables
92
+ sql = <<-EOS
93
+ select schemas.name + '.' + tables.name table_name
94
+ from sys.tables
95
+ inner join sys.schemas on schemas.schema_id = tables.schema_id
96
+ order by 1
97
+ EOS
98
+ QueryOutput.new(@connection, sql).show
99
+ @processed = true
100
+ end
101
+
102
+ def explain_object(schema, object)
103
+ sql = <<-EOS
104
+ declare @object_id int, @type varchar(2), @name varchar(255)
105
+
106
+ select @object_id = o.object_id, @type = o.type, @name = s.name + '.' + o.name
107
+ from sys.objects o
108
+ inner join sys.schemas s on o.schema_id = s.schema_id
109
+ where s.name = '#{schema}' and o.name = '#{object}'
110
+
111
+ --finding object with like in name, possibly confusing, so comment out
112
+ --if @object_id is null
113
+ -- select top 1 @object_id = o.object_id, @type = o.type, @name = s.name + '.' + o.name
114
+ -- from sys.objects o
115
+ -- inner join sys.schemas s on o.schema_id = s.schema_id
116
+ -- where s.name = '#{schema}' and o.name like '#{object}%'
117
+ -- order by s.schema_id, o.name
118
+
119
+ if @object_id is not null
120
+ if @type = 'U'
121
+ exec sp_help @name
122
+ else
123
+ select text from syscomments where id = @object_id
124
+ else
125
+ select 'object not found'
126
+ EOS
127
+
128
+ QueryOutput.new(@connection, sql).show_text_or_table
129
+ @processed = true
130
+ end
131
+
132
+
133
+ end