mssql 0.0.2

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.
@@ -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