csv2psql 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c574fd6b1d061c440819ab604708ccba37066764
4
- data.tar.gz: 303669c9e29f0ac4d6acb3486c571b1292a48019
3
+ metadata.gz: 017e866dc4a84a448f04c6d360ee95d215b8e6bc
4
+ data.tar.gz: 036e31c4b92508fb0d66942779378c8b11f46d94
5
5
  SHA512:
6
- metadata.gz: 885032b508c06b0a2cbe0596aeda0e6a07df4a1d0f5f6ae8ba566d8fdb5e37724120a937eb9722bcad25b0cee25290502c90aff5bf725700d31d8a40300494cb
7
- data.tar.gz: 37e881ed5a62e9eaf6f82c3496964f7c05db63693bad55348f2f2e48f5f838787be4fc5e0c003396fbc50e8c56751d87890823347b758d5f3105088290b3406f
6
+ metadata.gz: 6910eb4b0578c3a5699b494673e61f3dec5c1f98c0fe503e359e27e4804d8739258ec0fc8db6effed1df08728bae21b0cec63d02caccb6d1cea2933602e459ad
7
+ data.tar.gz: dc146c73e70760956c91a7b947eac86fb3d1f212f997c117ddea8b3a2b22be6ae402d15f1400107b565411c946235e6f86598e1fe5dccea6cf3c47fa92ee5c79
data/.gemspec CHANGED
@@ -29,8 +29,11 @@ Gem::Specification.new do |s|
29
29
  s.add_dependency 'rake', '~> 10.3', '>= 10.3.2'
30
30
  s.add_dependency 'terminal-table', '~> 1.4', '>= 1.4.5'
31
31
 
32
+ s.add_development_dependency 'codeclimate-test-reporter', '~> 0.4', '>= 0.4.0'
32
33
  s.add_development_dependency 'coveralls', '~> 0.7', '>= 0.7.0r'
34
+ s.add_development_dependency "redcarpet", "~> 3.1.1" if RUBY_PLATFORM != 'java'
33
35
  s.add_development_dependency 'rspec', '~> 3.0', '>= 3.0.0'
34
36
  s.add_development_dependency 'rubocop', '~> 0.24', '>= 0.24.0'
35
37
  s.add_development_dependency 'simplecov', '~> 0.8', '>= 0.8.2'
38
+ s.add_development_dependency 'yard', '~> 0.8.7.3'
36
39
  end
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec_helper
data/.yardopts ADDED
@@ -0,0 +1,15 @@
1
+ --protected
2
+ --no-private
3
+ --verbose
4
+ --markup markdown
5
+ --markup-provider redcarpet
6
+ --hide-void-return
7
+ --exclude LICENSE
8
+ --no-cache
9
+ --output-dir doc/html
10
+ lib/**/*.rb
11
+ ext/**/*{.m,.c}
12
+ spec/**/*_spec.rb
13
+ -
14
+ README.md
15
+ TODO.md
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in json2csv.gemspec
data/README.md CHANGED
@@ -15,7 +15,7 @@ Tool for transforming CSV into SQL statements
15
15
  [![Build Status](https://travis-ci.org/korczis/csv2psql.svg?branch=master)](https://travis-ci.org/korczis/csv2psql)
16
16
  [![Code Climate](https://codeclimate.com/github/korczis/csv2psql/badges/gpa.svg)](https://codeclimate.com/github/korczis/csv2psql)
17
17
  [![Dependency Status](https://gemnasium.com/korczis/csv2psql.svg)](https://gemnasium.com/korczis/csv2psql)
18
-
18
+ [![Coverage Status](https://coveralls.io/repos/korczis/csv2psql/badge.png?branch=master)](https://coveralls.io/r/korczis/csv2psql?branch=master)
19
19
 
20
20
  ## Features
21
21
 
@@ -48,7 +48,7 @@ csv2psql convert data/sample.csv
48
48
  csv2psql help
49
49
 
50
50
  NAME
51
- csv2psql - csv2psql 0.0.7 (Codename: Smelly cat)
51
+ csv2psql - csv2psql 0.0.9 (Codename: Flying fish)
52
52
 
53
53
  SYNOPSIS
54
54
  csv2psql [global options] command [command options] [arguments...]
@@ -61,11 +61,27 @@ GLOBAL OPTIONS
61
61
  -s, --separator=arg - Line separator (default: auto)
62
62
 
63
63
  COMMANDS
64
+ analyze - Analyze csv file
64
65
  convert - Convert csv file
65
66
  help - Shows a list of commands or help for one command
66
67
  version - Print version info
67
68
  ```
68
69
 
70
+ **Analyze help**
71
+
72
+ ```
73
+ csv2psql help analyze
74
+
75
+ NAME
76
+ analyze - Analyze csv file
77
+
78
+ SYNOPSIS
79
+ csv2psql [global options] analyze [command options]
80
+
81
+ COMMAND OPTIONS
82
+ -f, --format=arg - Output format (default: json)
83
+ ```
84
+
69
85
  **Convert help**
70
86
 
71
87
  ```
@@ -180,6 +196,30 @@ COMMIT;
180
196
  csv2psql convert --create-table --drop-table --truncate-table --no-transaction -t test data/cia-data-all.csv | psql
181
197
  ```
182
198
 
199
+ **Analyze CSV - Show as table**
200
+
201
+ ```
202
+ csv2psql analyze --format=table tmp/sfpd_incident_2013.csv
203
+
204
+ +------------+--------+-----------+---------+------+--------+------+
205
+ | tmp/sfpd_incident_2013.csv |
206
+ +------------+--------+-----------+---------+------+--------+------+
207
+ | column | Bigint | Character | Decimal | Null | String | Uuid |
208
+ +------------+--------+-----------+---------+------+--------+------+
209
+ | IncidntNum | 132145 | 0 | 0 | 0 | 132145 | 0 |
210
+ | Category | 0 | 0 | 0 | 0 | 132145 | 0 |
211
+ | Descript | 0 | 0 | 0 | 0 | 132145 | 0 |
212
+ | DayOfWeek | 0 | 0 | 0 | 0 | 132145 | 0 |
213
+ | Date | 0 | 0 | 0 | 0 | 132145 | 0 |
214
+ | Time | 0 | 0 | 0 | 0 | 132145 | 0 |
215
+ | PdDistrict | 0 | 0 | 0 | 0 | 132145 | 0 |
216
+ | Resolution | 0 | 0 | 0 | 0 | 132145 | 0 |
217
+ | Location | 0 | 0 | 0 | 0 | 132145 | 0 |
218
+ | X | 0 | 0 | 132145 | 0 | 132145 | 0 |
219
+ | Y | 0 | 0 | 132145 | 0 | 132145 | 0 |
220
+ +------------+--------+-----------+---------+------+--------+------+
221
+ ```
222
+
183
223
  ## Contributing to csv2psql
184
224
 
185
225
  - Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
data/Rakefile CHANGED
@@ -3,18 +3,21 @@
3
3
  require 'rubygems'
4
4
 
5
5
  require 'bundler/setup'
6
- require 'bundler/gem_tasks'
7
6
 
8
7
  require 'coveralls/rake/task'
9
8
 
10
9
  require 'rspec/core/rake_task'
11
10
 
11
+ require 'yard'
12
+
12
13
  Coveralls::RakeTask.new
13
14
 
14
15
  RSpec::Core::RakeTask.new(:test)
15
16
 
16
17
  desc 'Run continuous integration test'
17
18
  task :ci do
19
+ token = 'f9c7d31fe9fb2808cbb21642c4d1d20d1bfc1ba0d6321b10d7edf5725a5c8473'
20
+ ENV['CODECLIMATE_REPO_TOKEN'] = token
18
21
  Rake::Task['test:unit'].invoke
19
22
  # unless ENV['TRAVIS'] == 'true' && ENV['TRAVIS_SECURE_ENV_VARS'] == 'false'
20
23
  # Rake::Task['test:integration'].invoke
@@ -25,7 +28,11 @@ end
25
28
 
26
29
  desc 'Run Rubocop'
27
30
  task :cop do
28
- exec 'rubocop lib/'
31
+ exec 'rubocop lib/ spec/ templates/ Gemfile Rakefile'
32
+ end
33
+
34
+ namespace :gem do
35
+ require 'bundler/gem_tasks'
29
36
  end
30
37
 
31
38
  namespace :test do
@@ -34,17 +41,12 @@ namespace :test do
34
41
  t.pattern = 'spec/unit/**/*.rb'
35
42
  end
36
43
 
37
- desc "Run coding style tests"
38
- RSpec::Core::RakeTask.new(:cop) do |t|
44
+ desc 'Run coding style tests'
45
+ RSpec::Core::RakeTask.new(:cop) do |_t|
39
46
  Rake::Task['cop'].invoke
40
47
  end
41
48
 
42
- task :all => [:unit, :cop]
43
- end
44
-
45
- desc 'Get all tasks'
46
- task :tasklist do
47
- puts Rake.application.tasks
49
+ task all: [:unit, :cop]
48
50
  end
49
51
 
50
52
  task :usage do
@@ -52,8 +54,9 @@ task :usage do
52
54
  # puts "No rake task specified so listing them ..."
53
55
  # Rake.application['tasklist'].invoke
54
56
  end
55
- task :default => [:usage]
56
57
 
57
- if $0 == __FILE__
58
- Rake.application['usage'].invoke
59
- end
58
+ YARD::Rake::YardocTask.new
59
+
60
+ task default: [:usage]
61
+
62
+ Rake.application['usage'].invoke if __FILE__ == $PROGRAM_NAME
data/TODO.md CHANGED
@@ -4,9 +4,12 @@ List od task to do
4
4
 
5
5
  ## Tasks
6
6
 
7
+ - Offset, Limit
8
+ - Custom types
7
9
  - Column names override
8
10
  - Data type detection
9
11
  - Include/Exclude columns
10
12
  - Column datatype guesser (with sha based caching of results)
11
13
  - Templates override
12
- - Custom row formater - no need to override templates
14
+ - Custom row formatter - no need to override templates
15
+ - Transformers
data/bin/csv2psql CHANGED
@@ -3,4 +3,6 @@
3
3
  require_relative '../lib/csv2psql/lib'
4
4
  require_relative '../lib/csv2psql/version'
5
5
 
6
- require_relative '../lib/csv2psql/cli/cli'
6
+ require_relative '../lib/csv2psql/cli/cli'
7
+
8
+ Csv2Psql::Cli.main if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,3 @@
1
+ id;Firstname;Lastname;Address.Street;Address.City;Address.Details.Note
2
+ 12345;Joe;Doe,"#2140 Taylor Street, 94133";San Francisco;Pool available
3
+ 45678;Jack;Plumber;"#111 Sutter St, 94104";San Francisco;Korean Deli near to main entrance
@@ -5,6 +5,8 @@ module Csv2Psql
5
5
  # Bigint value matcher
6
6
  class Bigint
7
7
  TYPE = :bigint
8
+ CLASS = :numeric
9
+ WEIGHT = 4
8
10
 
9
11
  attr_reader :count, :min, :max
10
12
 
@@ -24,6 +26,14 @@ module Csv2Psql
24
26
  val.to_i
25
27
  end
26
28
 
29
+ def to_h
30
+ {
31
+ count: @count,
32
+ min: @min,
33
+ max: @max
34
+ }
35
+ end
36
+
27
37
  def update(val)
28
38
  @count += 1
29
39
  @min = val if @min.nil? || val < @min
@@ -5,6 +5,8 @@ module Csv2Psql
5
5
  # Character value matcher
6
6
  class Character
7
7
  TYPE = :bigint
8
+ CLASS = :character
9
+ WEIGHT = 2
8
10
 
9
11
  attr_reader :count
10
12
 
@@ -17,6 +19,12 @@ module Csv2Psql
17
19
  return unless match
18
20
  @count += 1
19
21
  end
22
+
23
+ def to_h
24
+ {
25
+ count: @count
26
+ }
27
+ end
20
28
  end
21
29
  end
22
30
  end
@@ -5,6 +5,8 @@ module Csv2Psql
5
5
  # Decimal value matcher
6
6
  class Decimal
7
7
  TYPE = :decimal
8
+ CLASS = :numeric
9
+ WEIGHT = 3
8
10
 
9
11
  attr_reader :count, :min, :max
10
12
 
@@ -24,6 +26,14 @@ module Csv2Psql
24
26
  val.to_f
25
27
  end
26
28
 
29
+ def to_h
30
+ {
31
+ count: @count,
32
+ min: @min,
33
+ max: @max
34
+ }
35
+ end
36
+
27
37
  def update(val)
28
38
  @count += 1
29
39
  @min = val if @min.nil? || val < @min
@@ -5,6 +5,8 @@ module Csv2Psql
5
5
  # Null value matcher
6
6
  class Null
7
7
  TYPE = :null
8
+ CLASS = nil # TODO: Maybe use better class for Null type?
9
+ WEIGHT = 0
8
10
 
9
11
  attr_reader :count
10
12
 
@@ -17,6 +19,12 @@ module Csv2Psql
17
19
  return unless match
18
20
  @count += 1
19
21
  end
22
+
23
+ def to_h
24
+ {
25
+ count: @count
26
+ }
27
+ end
20
28
  end
21
29
  end
22
30
  end
@@ -0,0 +1,37 @@
1
+ # encoding: UTF-8
2
+
3
+ module Csv2Psql
4
+ module Analyzers
5
+ # UUID value matcher
6
+ class String
7
+ TYPE = :string
8
+ CLASS = :character
9
+ WEIGHT = 1
10
+
11
+ attr_reader :count, :min, :max
12
+
13
+ def initialize
14
+ @count = 0
15
+ @min = nil
16
+ @max = nil
17
+ end
18
+
19
+ def analyze(val)
20
+ match = val.is_a?(::String)
21
+ return unless match
22
+ len = val.length
23
+ @min = len if @min.nil? || len < @min
24
+ @max = len if @max.nil? || len > @max
25
+ @count += 1
26
+ end
27
+
28
+ def to_h
29
+ {
30
+ count: @count,
31
+ min: @min,
32
+ max: @max
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -5,6 +5,9 @@ module Csv2Psql
5
5
  # UUID value matcher
6
6
  class Uuid
7
7
  TYPE = :uuid
8
+ CLASS = :uuid
9
+ WEIGHT = 5
10
+
8
11
  RE = /[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/ # rubocop:disable Metrics/LineLength
9
12
 
10
13
  attr_reader :count
@@ -18,6 +21,12 @@ module Csv2Psql
18
21
  return if match.nil?
19
22
  @count += 1
20
23
  end
24
+
25
+ def to_h
26
+ {
27
+ count: @count
28
+ }
29
+ end
21
30
  end
22
31
  end
23
32
  end
@@ -29,6 +29,12 @@ cmds = {
29
29
  default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:delimiter]
30
30
  },
31
31
 
32
+ l: {
33
+ desc: 'How many rows process',
34
+ type: Integer,
35
+ default_value: -1
36
+ },
37
+
32
38
  q: {
33
39
  desc: 'Quoting character',
34
40
  type: String,
@@ -39,13 +45,21 @@ cmds = {
39
45
  desc: 'Line separator',
40
46
  type: String,
41
47
  default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:separator]
48
+ },
49
+
50
+ 'skip' => {
51
+ desc: 'How many rows skip',
52
+ type: Integer,
53
+ default_value: -1
42
54
  }
43
55
  }
44
56
 
45
57
  switch [:h, :header], cmds[:h]
46
58
  flag [:d, :delimiter], cmds[:d]
59
+ flag [:l, :limit], cmds[:l]
47
60
  flag [:q, :quote], cmds[:q]
48
61
  flag [:s, :separator], cmds[:s]
62
+ flag [:skip], cmds['skip']
49
63
 
50
64
  module Csv2Psql
51
65
  # Apollon CLI
@@ -66,4 +80,4 @@ module Csv2Psql
66
80
  end
67
81
  end
68
82
 
69
- launch
83
+ launch if __FILE__ == $PROGRAM_NAME
@@ -1,7 +1,31 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'pathname'
3
+ require 'gli'
4
+ require 'pp'
4
5
 
5
- require_relative 'shared'
6
+ # Define Csv2Psql::Cli as GLI Wrapper
7
+ module Csv2Psql
8
+ # CLI/GLI Wrapper
9
+ module Cli
10
+ include GLI::App
6
11
 
7
- require_relative 'app'
12
+ # Require shared part of GLI::App - flags, meta, etc
13
+ require_relative 'shared.rb'
14
+
15
+ # Require Hooks
16
+ # require_relative 'hooks.rb'
17
+
18
+ base = File.join(File.dirname(__FILE__), 'cmd')
19
+ Dir[base + '/**/*.rb'].each do |f|
20
+ require f
21
+ end
22
+
23
+ # GLI::App.commands_from(File.join(File.dirname(__FILE__), 'cmd'))
24
+
25
+ def self.main(args = ARGV)
26
+ run(args)
27
+ end
28
+ end
29
+ end
30
+
31
+ Csv2Psql::Cli.main(ARGV) if __FILE__ == $PROGRAM_NAME
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'gli'
4
+ require 'json'
4
5
  require 'pp'
5
6
  require 'terminal-table'
6
7
 
@@ -10,23 +11,65 @@ require_relative '../shared'
10
11
  require_relative '../../convert/convert'
11
12
  require_relative '../../processor/processor'
12
13
 
13
- desc 'Analyze csv file'
14
- command :analyze do |c|
15
- c.action do |global_options, options, args|
16
- fail ArgumentError, 'No file to analyze specified' if args.empty?
14
+ Csv2Psql::Cli.module_eval do
15
+ formats = {
16
+ 'json' => lambda do |res|
17
+ res.files.each do |_fname, results|
18
+ results[:columns].each do |_k, v|
19
+ v.each do |d, det|
20
+ v[d] = det.to_h
21
+ end
22
+ end
23
+ end
24
+
25
+ JSON.pretty_generate(res.files)
26
+ end,
27
+
28
+ 'table' => lambda do |res|
29
+ res.files.map do |file, details|
30
+ header = ['column'] + res.analyzers.map { |a| a[:name] }
31
+
32
+ rows = details[:columns].map do |k, v|
33
+ [k] + v.keys.map { |name| v[name].count }
34
+ end
35
+
36
+ Terminal::Table.new title: file, headings: header, rows: rows
37
+ end
38
+ end
39
+ }
40
+
41
+ cmds = {
42
+ f: {
43
+ desc: 'Output format',
44
+ type: String,
45
+ default_value: formats.keys.first
46
+ }
47
+ }
17
48
 
18
- opts = {}.merge(global_options).merge(options)
19
- res = Csv2Psql::Convert.analyze(args, opts)
49
+ desc 'Analyze csv file'
50
+ command :analyze do |c|
51
+ c.flag [:f, :format], cmds[:f]
20
52
 
21
- res.files.each do |_file, details|
22
- header = ['column'] + res.analyzers.map { |a| a[:name] }
53
+ c.action do |global_options, options, args|
54
+ fail ArgumentError, 'No file to analyze specified' if args.empty?
23
55
 
24
- rows = details[:columns].map do |k, v|
25
- [k] + v.keys.map { |name| v[name].count }
56
+ opts = {}.merge(global_options).merge(options)
57
+ res = Csv2Psql::Convert.analyze(args, opts)
58
+
59
+ formater = formats[opts[:format]]
60
+ if formater.nil?
61
+ fmters = formats.keys.join(', ')
62
+ fail ArgumentError, "Wrong formatter specified, can be: #{fmters}"
26
63
  end
27
64
 
28
- table = Terminal::Table.new headings: header, rows: rows
29
- puts table
65
+ output = formater.call(res)
66
+ if output.is_a?(Array)
67
+ output.each do |o|
68
+ puts o
69
+ end
70
+ else
71
+ puts output
72
+ end
30
73
  end
31
74
  end
32
75
  end
@@ -8,48 +8,48 @@ require_relative '../shared'
8
8
  require_relative '../../convert/convert'
9
9
  require_relative '../../processor/processor'
10
10
 
11
- cmds = {
12
- t: {
13
- desc: 'Table to insert to',
14
- type: String,
15
- default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:table]
16
- },
17
-
18
- transaction: {
19
- desc: 'Import in transaction block',
20
- default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:transaction]
21
- },
22
-
23
- 'create-table' => {
24
- desc: 'Crate SQL Table before inserts',
25
- default_value: Csv2Psql::Processor::DEFAULT_OPTIONS['create-table']
26
- },
27
-
28
- 'drop-table' => {
29
- desc: 'Drop SQL Table before inserts',
30
- default_value: Csv2Psql::Processor::DEFAULT_OPTIONS['drop-table']
31
- },
32
-
33
- 'truncate-table' => {
34
- desc: 'Truncate SQL Table before inserts',
35
- default_value: Csv2Psql::Processor::DEFAULT_OPTIONS['truncate-table']
11
+ Csv2Psql::Cli.module_eval do
12
+ cmds = {
13
+ t: {
14
+ desc: 'Table to insert to',
15
+ type: String,
16
+ default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:table]
17
+ },
18
+
19
+ transaction: {
20
+ desc: 'Import in transaction block',
21
+ default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:transaction]
22
+ },
23
+
24
+ 'create-table' => {
25
+ desc: 'Crate SQL Table before inserts',
26
+ default_value: Csv2Psql::Processor::DEFAULT_OPTIONS['create-table']
27
+ },
28
+
29
+ 'drop-table' => {
30
+ desc: 'Drop SQL Table before inserts',
31
+ default_value: Csv2Psql::Processor::DEFAULT_OPTIONS['drop-table']
32
+ },
33
+
34
+ 'truncate-table' => {
35
+ desc: 'Truncate SQL Table before inserts',
36
+ default_value: Csv2Psql::Processor::DEFAULT_OPTIONS['truncate-table']
37
+ }
36
38
  }
37
- }
38
39
 
39
- desc 'Convert csv file'
40
- command :convert do |c|
41
- c.flag [:t, :table], cmds[:t]
42
- c.switch [:transaction], cmds[:transaction]
43
- c.switch ['create-table'], cmds['create-table']
44
- c.switch ['drop-table'], cmds['drop-table']
45
- c.switch ['truncate-table'], cmds['truncate-table']
40
+ desc 'Convert csv file'
41
+ command :convert do |c|
42
+ c.flag [:t, :table], cmds[:t]
43
+ c.switch [:transaction], cmds[:transaction]
44
+ c.switch ['create-table'], cmds['create-table']
45
+ c.switch ['drop-table'], cmds['drop-table']
46
+ c.switch ['truncate-table'], cmds['truncate-table']
46
47
 
47
- c.action do |global_options, options, args|
48
- fail ArgumentError, 'No file to convert specified' if args.empty?
48
+ c.action do |global_options, options, args|
49
+ fail ArgumentError, 'No file to convert specified' if args.empty?
49
50
 
50
- opts = {}.merge(global_options).merge(options)
51
- Csv2Psql::Convert.convert(args, opts)
51
+ opts = {}.merge(global_options).merge(options)
52
+ Csv2Psql::Convert.convert(args, opts)
53
+ end
52
54
  end
53
55
  end
54
-
55
- # default_command :convert
@@ -8,9 +8,11 @@ require_relative '../../version'
8
8
 
9
9
  require_relative '../shared'
10
10
 
11
- desc 'Print version info'
12
- command :version do |c|
13
- c.action do |_global_options, _options, _args|
14
- pp Csv2Psql::VERSION
11
+ Csv2Psql::Cli.module_eval do
12
+ desc 'Print version info'
13
+ command :version do |c|
14
+ c.action do |_global_options, _options, _args|
15
+ pp Csv2Psql::VERSION
16
+ end
15
17
  end
16
18
  end
@@ -2,11 +2,55 @@
2
2
 
3
3
  require 'gli'
4
4
 
5
- module Csv2Psql
6
- module Cli
7
- # Shared CLI Stuff
8
- module Shared
9
- extend GLI::App
10
- end
11
- end
5
+ require_relative '../version'
6
+ require_relative '../processor/processor'
7
+
8
+ include GLI::App
9
+
10
+ Csv2Psql::Cli.module_eval do
11
+ program_desc "csv2psql #{Csv2Psql::VERSION} (Codename: #{Csv2Psql::CODENAME})"
12
+
13
+ cmds = {
14
+ h: {
15
+ desc: 'Header row included',
16
+ default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:header]
17
+ },
18
+
19
+ d: {
20
+ desc: 'Column delimiter',
21
+ type: String,
22
+ default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:delimiter]
23
+ },
24
+
25
+ l: {
26
+ desc: 'How many rows process',
27
+ type: Integer,
28
+ default_value: -1
29
+ },
30
+
31
+ q: {
32
+ desc: 'Quoting character',
33
+ type: String,
34
+ default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:quote]
35
+ },
36
+
37
+ s: {
38
+ desc: 'Line separator',
39
+ type: String,
40
+ default_value: Csv2Psql::Processor::DEFAULT_OPTIONS[:separator]
41
+ },
42
+
43
+ 'skip' => {
44
+ desc: 'How many rows skip',
45
+ type: Integer,
46
+ default_value: -1
47
+ }
48
+ }
49
+
50
+ switch [:h, :header], cmds[:h]
51
+ flag [:d, :delimiter], cmds[:d]
52
+ flag [:l, :limit], cmds[:l]
53
+ flag [:q, :quote], cmds[:q]
54
+ flag [:s, :separator], cmds[:s]
55
+ flag [:skip], cmds['skip']
12
56
  end
@@ -10,7 +10,7 @@ require_relative '../helpers/csv_helper'
10
10
  require_relative '../helpers/erb_helper'
11
11
 
12
12
  module Csv2Psql
13
- # Csv2Psql type guesser class
13
+ # SQL Code generator
14
14
  class Generator
15
15
  BASE_DIR = File.join(File.dirname(__FILE__), '..', '..', '..')
16
16
  TEMPLATE_DIR = File.join(BASE_DIR, 'templates')
@@ -9,7 +9,7 @@ require_relative '../version'
9
9
  require_relative '../helpers/erb_helper'
10
10
 
11
11
  module Csv2Psql
12
- # Csv2Psql type guesser class
12
+ # Output/writer/executor class
13
13
  class Output
14
14
  def write(str)
15
15
  puts str
@@ -33,25 +33,42 @@ module Csv2Psql
33
33
 
34
34
  def analyze(paths, opts = {})
35
35
  with_paths(paths, opts) do |data|
36
- path = data[:path]
37
- row = data[:row]
38
- analyzer.analyze(path, row, opts)
36
+ analyzer.analyze(data[:path], data[:row], opts)
39
37
  end
40
38
  analyzer
41
39
  end
42
40
 
43
41
  def convert(paths, opts = {})
44
- file_headers = {}
45
-
42
+ details = {}
46
43
  with_paths(paths, opts) do |data|
47
- path = data[:path]
48
- row = data[:row]
49
- unless file_headers.key?(path)
50
- generator.create_sql_script(path, row, opts)
51
- file_headers[path] = true
52
- end
44
+ create_converted_header(details, data, opts)
45
+
46
+ output.write generator.format_row(data[:row], opts)
47
+ end
48
+ end
49
+
50
+ def create_converted_header(details, data, opts = {})
51
+ detail = get_file_details(details, data[:path])
52
+ unless detail[:header] # rubocop:disable Style/GuardClause
53
+ generator.create_sql_script(data[:path], data[:row], opts)
54
+ detail[:header] = true
55
+ end
56
+ end
57
+
58
+ def create_file_details(files, path)
59
+ files[path] = {
60
+ header: false,
61
+ lines: 0,
62
+ line: 0
63
+ }
64
+ files[path]
65
+ end
53
66
 
54
- output.write generator.format_row(row, opts)
67
+ def get_file_details(files, path)
68
+ if files.key?(path)
69
+ files[path]
70
+ else
71
+ create_file_details(files, path)
55
72
  end
56
73
  end
57
74
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  # Csv2Psql module
4
4
  module Csv2Psql
5
- CODENAME = 'Flying fish'
6
- VERSION = '0.0.9'
5
+ CODENAME = 'Lazy dog'
6
+ VERSION = '0.0.10'
7
7
  end
@@ -0,0 +1,9 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative '../../lib/csv2psql/cli/cli'
4
+
5
+ describe 'csv2psql' do
6
+ it 'help' do
7
+ run_cli(['help'])
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative '../../../lib/csv2psql/cli/cli'
4
+
5
+ describe 'csv2psql analyze' do
6
+ it 'help analyze' do
7
+ run_cli(%w(help analyze))
8
+ end
9
+
10
+ it 'analyze data/cia-data-all.csv' do
11
+ run_cli(%w(analyze data/cia-data-all.csv))
12
+ end
13
+
14
+ it 'analyze data/sample.csv' do
15
+ run_cli(%w(analyze data/sample.csv))
16
+ end
17
+
18
+ it '--delimiter ";" analyze data/sample.csv' do
19
+ run_cli(%w(analyze --delimiter ";" data/sample_semicolon.csv))
20
+ end
21
+
22
+ it 'analyze --format json data/sample.csv' do
23
+ run_cli(%w(analyze --format json data/sample.csv))
24
+ end
25
+
26
+ it 'analyze --format table data/sample.csv' do
27
+ run_cli(%w(analyze --format table data/sample.csv))
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative '../../../lib/csv2psql/cli/cli'
4
+
5
+ describe 'csv2psql convert' do
6
+ it 'help convert' do
7
+ run_cli(%w(help convert))
8
+ end
9
+
10
+ it 'convert data/cia-data-all.csv' do
11
+ run_cli(%w(convert data/cia-data-all.csv))
12
+ end
13
+
14
+ it 'convert data/sample.csv' do
15
+ run_cli(%w(convert data/sample.csv))
16
+ end
17
+
18
+ it 'convert --drop-table data/sample.csv' do
19
+ run_cli(%w(convert --drop-table data/sample.csv))
20
+ end
21
+
22
+ it 'convert --drop-table --create-table data/sample.csv' do
23
+ run_cli(%w(convert --drop-table --create-table data/sample.csv))
24
+ end
25
+
26
+ it 'convert --drop-table --create-table --truncate-table data/sample.csv' do
27
+ args = %w(
28
+ convert
29
+ --drop-table
30
+ --create-table
31
+ --truncate-table
32
+ data/sample.csv
33
+ )
34
+ run_cli(args)
35
+ end
36
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative '../../../lib/csv2psql/cli/cli'
4
+
5
+ describe 'csv2psql version' do
6
+ it 'version' do
7
+ run_cli(%w(version))
8
+ end
9
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative '../../lib/csv2psql/cli/cli'
4
+
5
+ # CliHelper
6
+ module CliHelper
7
+ # Execute block and capture its stdou
8
+ # @param block Block to be executed with stdout redirected
9
+ # @returns Captured output as string
10
+ def capture_stdout(&block)
11
+ original_stdout = $stdout
12
+ $stdout = fake = StringIO.new
13
+ begin
14
+ block.call if block_given?
15
+ ensure
16
+ $stdout = original_stdout
17
+ end
18
+ fake.string
19
+ end
20
+
21
+ # Run CLI with arguments and return captured stdout
22
+ # @param args Arguments
23
+ # @return Captured stdout
24
+ def run_cli(args = [])
25
+ old = $PROGRAM_NAME
26
+ $PROGRAM_NAME = 'csv2psql'
27
+ res = capture_stdout { Csv2Psql::Cli.main(args) }
28
+ $PROGRAM_NAME = old
29
+ res
30
+ end
31
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'codeclimate-test-reporter'
3
4
  require 'simplecov'
4
5
  require 'rspec'
5
6
  require 'coveralls'
6
7
  require 'pathname'
7
8
 
9
+ CodeClimate::TestReporter.start
10
+
8
11
  Coveralls.wear_merged!
9
12
 
10
13
  # Automagically include all helpers/*_helper.rb
@@ -15,7 +18,9 @@ Dir.glob(base + 'helpers/*_helper.rb').each do |file|
15
18
  end
16
19
 
17
20
  RSpec.configure do |config|
18
- config.filter_run_excluding :broken => true
21
+ config.include CliHelper
22
+
23
+ config.filter_run_excluding broken: true
19
24
 
20
25
  config.before(:all) do
21
26
  # TODO: Fully setup global environment
@@ -41,4 +46,4 @@ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
41
46
 
42
47
  SimpleCov.start do
43
48
  add_filter 'spec/'
44
- end
49
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv2psql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas Korcak
@@ -98,6 +98,26 @@ dependencies:
98
98
  - - ">="
99
99
  - !ruby/object:Gem::Version
100
100
  version: 1.4.5
101
+ - !ruby/object:Gem::Dependency
102
+ name: codeclimate-test-reporter
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '0.4'
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 0.4.0
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.4'
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 0.4.0
101
121
  - !ruby/object:Gem::Dependency
102
122
  name: coveralls
103
123
  requirement: !ruby/object:Gem::Requirement
@@ -118,6 +138,20 @@ dependencies:
118
138
  - - ">="
119
139
  - !ruby/object:Gem::Version
120
140
  version: 0.7.0r
141
+ - !ruby/object:Gem::Dependency
142
+ name: redcarpet
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - "~>"
146
+ - !ruby/object:Gem::Version
147
+ version: 3.1.1
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - "~>"
153
+ - !ruby/object:Gem::Version
154
+ version: 3.1.1
121
155
  - !ruby/object:Gem::Dependency
122
156
  name: rspec
123
157
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +212,20 @@ dependencies:
178
212
  - - ">="
179
213
  - !ruby/object:Gem::Version
180
214
  version: 0.8.2
215
+ - !ruby/object:Gem::Dependency
216
+ name: yard
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - "~>"
220
+ - !ruby/object:Gem::Version
221
+ version: 0.8.7.3
222
+ type: :development
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - "~>"
227
+ - !ruby/object:Gem::Version
228
+ version: 0.8.7.3
181
229
  description: CSV to SQL conversion tool with user friendly CLI
182
230
  email: korczis@gmail.com
183
231
  executables:
@@ -187,7 +235,9 @@ extra_rdoc_files: []
187
235
  files:
188
236
  - ".gemspec"
189
237
  - ".gitignore"
238
+ - ".rspec"
190
239
  - ".travis.yml"
240
+ - ".yardopts"
191
241
  - Gemfile
192
242
  - LICENSE
193
243
  - README.md
@@ -196,12 +246,14 @@ files:
196
246
  - bin/csv2psql
197
247
  - data/cia-data-all.csv
198
248
  - data/sample.csv
249
+ - data/sample_semicolons.csv
199
250
  - lib/csv2psql.rb
200
251
  - lib/csv2psql/analyzer/analyzer.rb
201
252
  - lib/csv2psql/analyzer/types/bigint.rb
202
253
  - lib/csv2psql/analyzer/types/character.rb
203
254
  - lib/csv2psql/analyzer/types/decimal.rb
204
255
  - lib/csv2psql/analyzer/types/null.rb
256
+ - lib/csv2psql/analyzer/types/string.rb
205
257
  - lib/csv2psql/analyzer/types/uuid.rb
206
258
  - lib/csv2psql/cli/app.rb
207
259
  - lib/csv2psql/cli/cli.rb
@@ -219,6 +271,11 @@ files:
219
271
  - lib/csv2psql/output/output.rb
220
272
  - lib/csv2psql/processor/processor.rb
221
273
  - lib/csv2psql/version.rb
274
+ - spec/cli/app_spec.rb
275
+ - spec/cli/cmd/analyze_cmd_spec.rb
276
+ - spec/cli/cmd/convert_cmd_spec.rb
277
+ - spec/cli/cmd/version_cmd_spec.rb
278
+ - spec/helpers/cli_helper.rb
222
279
  - spec/spec_helper.rb
223
280
  - templates/create_table.sql.erb
224
281
  - templates/drop_table.sql.erb
@@ -249,3 +306,4 @@ signing_key:
249
306
  specification_version: 4
250
307
  summary: Tool for converting CSV into SQL statements
251
308
  test_files: []
309
+ has_rdoc: