baza 0.0.19 → 0.0.20

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.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +157 -0
  3. data/Gemfile +11 -9
  4. data/Gemfile.lock +41 -9
  5. data/README.md +1 -1
  6. data/Rakefile +19 -16
  7. data/VERSION +1 -1
  8. data/baza.gemspec +31 -7
  9. data/config/best_project_practice_rubocop.yml +2 -0
  10. data/config/best_project_practice_rubocop_todo.yml +157 -0
  11. data/lib/baza/base_sql_driver.rb +79 -20
  12. data/lib/baza/cloner.rb +2 -2
  13. data/lib/baza/column.rb +6 -0
  14. data/lib/baza/database.rb +33 -0
  15. data/lib/baza/database_model.rb +26 -0
  16. data/lib/baza/database_model_functionality.rb +10 -0
  17. data/lib/baza/database_model_name.rb +16 -0
  18. data/lib/baza/db.rb +210 -413
  19. data/lib/baza/dbtime.rb +20 -20
  20. data/lib/baza/driver.rb +3 -3
  21. data/lib/baza/drivers/active_record/columns.rb +1 -1
  22. data/lib/baza/drivers/active_record/indexes.rb +1 -1
  23. data/lib/baza/drivers/active_record/result.rb +3 -5
  24. data/lib/baza/drivers/active_record/tables.rb +2 -2
  25. data/lib/baza/drivers/active_record.rb +30 -16
  26. data/lib/baza/drivers/mysql/column.rb +51 -48
  27. data/lib/baza/drivers/mysql/columns.rb +8 -8
  28. data/lib/baza/drivers/mysql/database.rb +28 -0
  29. data/lib/baza/drivers/mysql/databases.rb +35 -0
  30. data/lib/baza/drivers/mysql/index.rb +32 -22
  31. data/lib/baza/drivers/mysql/result.rb +24 -24
  32. data/lib/baza/drivers/mysql/sqlspecs.rb +1 -1
  33. data/lib/baza/drivers/mysql/table.rb +80 -91
  34. data/lib/baza/drivers/mysql/tables.rb +30 -32
  35. data/lib/baza/drivers/mysql/unbuffered_result.rb +5 -5
  36. data/lib/baza/drivers/mysql.rb +127 -220
  37. data/lib/baza/drivers/mysql2/database.rb +2 -0
  38. data/lib/baza/drivers/mysql2/databases.rb +2 -0
  39. data/lib/baza/drivers/mysql2/result.rb +3 -5
  40. data/lib/baza/drivers/mysql2.rb +21 -106
  41. data/lib/baza/drivers/mysql_java/database.rb +2 -0
  42. data/lib/baza/drivers/mysql_java/databases.rb +2 -0
  43. data/lib/baza/drivers/mysql_java.rb +16 -12
  44. data/lib/baza/drivers/sqlite3/column.rb +33 -33
  45. data/lib/baza/drivers/sqlite3/columns.rb +6 -6
  46. data/lib/baza/drivers/sqlite3/database.rb +2 -0
  47. data/lib/baza/drivers/sqlite3/databases.rb +25 -0
  48. data/lib/baza/drivers/sqlite3/index.rb +20 -6
  49. data/lib/baza/drivers/sqlite3/result.rb +16 -17
  50. data/lib/baza/drivers/sqlite3/sqlspecs.rb +1 -1
  51. data/lib/baza/drivers/sqlite3/table.rb +99 -100
  52. data/lib/baza/drivers/sqlite3/tables.rb +30 -23
  53. data/lib/baza/drivers/sqlite3/unbuffered_result.rb +2 -2
  54. data/lib/baza/drivers/sqlite3.rb +27 -14
  55. data/lib/baza/drivers/sqlite3_java/database.rb +2 -0
  56. data/lib/baza/drivers/sqlite3_java/unbuffered_result.rb +2 -2
  57. data/lib/baza/drivers/sqlite3_java.rb +12 -10
  58. data/lib/baza/drivers/sqlite3_rhodes.rb +9 -7
  59. data/lib/baza/dump.rb +55 -55
  60. data/lib/baza/errors.rb +5 -0
  61. data/lib/baza/idquery.rb +25 -25
  62. data/lib/baza/index.rb +6 -0
  63. data/lib/baza/jdbc_driver.rb +6 -8
  64. data/lib/baza/jdbc_result.rb +1 -1
  65. data/lib/baza/model.rb +299 -309
  66. data/lib/baza/model_custom.rb +74 -72
  67. data/lib/baza/model_handler.rb +244 -255
  68. data/lib/baza/model_handler_sqlhelper.rb +122 -132
  69. data/lib/baza/mysql_base_driver.rb +112 -0
  70. data/lib/baza/query_buffer.rb +23 -23
  71. data/lib/baza/result_base.rb +2 -2
  72. data/lib/baza/revision.rb +67 -67
  73. data/lib/baza/row.rb +82 -84
  74. data/lib/baza/sqlspecs.rb +1 -1
  75. data/lib/baza/table.rb +31 -0
  76. data/lib/baza.rb +43 -10
  77. data/shippable.yml +1 -0
  78. data/spec/cloner_spec.rb +4 -4
  79. data/spec/drivers/active_record_mysql2_spec.rb +3 -3
  80. data/spec/drivers/active_record_mysql_spec.rb +2 -2
  81. data/spec/drivers/active_record_sqlite3_spec.rb +2 -2
  82. data/spec/drivers/mysql2_spec.rb +1 -0
  83. data/spec/drivers/mysql_spec.rb +1 -0
  84. data/spec/drivers/sqlite3_spec.rb +4 -5
  85. data/spec/info_active_record_example.rb +4 -6
  86. data/spec/info_active_record_mysql.rb +6 -7
  87. data/spec/info_active_record_mysql2.rb +2 -4
  88. data/spec/info_active_record_mysql2_shippable.rb +2 -4
  89. data/spec/info_active_record_mysql_shippable.rb +2 -4
  90. data/spec/info_active_record_sqlite3.rb +5 -6
  91. data/spec/info_mysql2_example.rb +1 -1
  92. data/spec/info_mysql2_shippable.rb +1 -1
  93. data/spec/info_mysql_example.rb +1 -1
  94. data/spec/info_mysql_shippable.rb +1 -1
  95. data/spec/info_sqlite3.rb +4 -3
  96. data/spec/model_handler_spec.rb +102 -115
  97. data/spec/spec_helper.rb +5 -5
  98. data/spec/support/driver_collection.rb +98 -95
  99. data/spec/support/driver_columns_collection.rb +18 -22
  100. data/spec/support/driver_databases_collection.rb +29 -0
  101. data/spec/support/driver_indexes_collection.rb +7 -6
  102. data/spec/support/driver_tables_collection.rb +38 -26
  103. metadata +49 -3
@@ -1,7 +1,9 @@
1
- #This class handels SQLite3-specific behaviour.
1
+ # This class handels SQLite3-specific behaviour.
2
2
  class Baza::Driver::Sqlite3Java < Baza::JdbcDriver
3
3
  path = "#{File.dirname(__FILE__)}/sqlite3_java"
4
4
 
5
+ autoload :Database, "#{path}/database"
6
+ autoload :Databases, "#{path}/databases"
5
7
  autoload :Table, "#{path}/table"
6
8
  autoload :Tables, "#{path}/tables"
7
9
  autoload :Column, "#{path}/column"
@@ -14,7 +16,7 @@ class Baza::Driver::Sqlite3Java < Baza::JdbcDriver
14
16
 
15
17
  attr_reader :mutex_statement_reader
16
18
 
17
- #Helper to enable automatic registering of database using Baza::Db.from_object
19
+ # Helper to enable automatic registering of database using Baza::Db.from_object
18
20
  def self.from_object(args)
19
21
  if args[:object].class.name == "Java::OrgSqlite::SQLiteConnection"
20
22
  return {
@@ -27,7 +29,7 @@ class Baza::Driver::Sqlite3Java < Baza::JdbcDriver
27
29
  end
28
30
  end
29
31
 
30
- #Constructor. This should not be called manually.
32
+ # Constructor. This should not be called manually.
31
33
  def initialize(baza_db)
32
34
  super
33
35
 
@@ -46,19 +48,19 @@ class Baza::Driver::Sqlite3Java < Baza::JdbcDriver
46
48
  raise "No path was given." unless @path
47
49
 
48
50
  @stmt = nil
49
- @conn = java.sql.DriverManager::getConnection("jdbc:sqlite:#{@path}")
51
+ @conn = java.sql.DriverManager.getConnection("jdbc:sqlite:#{@path}")
50
52
  end
51
53
 
52
- #Escapes a string to be safe to used in a query.
54
+ # Escapes a string to be safe to used in a query.
53
55
  def escape(string)
54
- #This code is taken directly from the documentation so we dont have to rely on the SQLite3::Database class. This way it can also be used with JRuby and IronRuby...
55
- #http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html
56
- return string.to_s.gsub(/'/, "''")
56
+ # This code is taken directly from the documentation so we dont have to rely on the SQLite3::Database class. This way it can also be used with JRuby and IronRuby...
57
+ # http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html
58
+ string.to_s.gsub(/'/, "''")
57
59
  end
58
60
 
59
- #Returns the last inserted ID.
61
+ # Returns the last inserted ID.
60
62
  def last_id
61
- return query("SELECT LAST_INSERT_ROWID() AS id").fetch[:id].to_i
63
+ query("SELECT LAST_INSERT_ROWID() AS id").fetch[:id].to_i
62
64
  end
63
65
 
64
66
  def transaction
@@ -1,7 +1,9 @@
1
- #This class handels SQLite3-specific behaviour.
1
+ # This class handels SQLite3-specific behaviour.
2
2
  class Baza::Driver::Sqlite3Rhodes < Baza::BaseSqlDriver
3
3
  path = "#{File.dirname(__FILE__)}/sqlite3_rhodes"
4
4
 
5
+ autoload :Database, "#{path}/database"
6
+ autoload :Databases, "#{path}/databases"
5
7
  autoload :Table, "#{path}/table"
6
8
  autoload :Tables, "#{path}/tables"
7
9
  autoload :Column, "#{path}/column"
@@ -44,24 +46,24 @@ class Baza::Driver::Sqlite3Rhodes < Baza::BaseSqlDriver
44
46
 
45
47
  # Executes a query against the driver.
46
48
  def query(sql)
47
- return Baza::Driver::Sqlite3::Result.new(self, @conn.execute(sql, sql))
49
+ Baza::Driver::Sqlite3::Result.new(self, @conn.execute(sql, sql))
48
50
  end
49
51
 
50
52
  def query_ubuf(sql)
51
- return Baza::Driver::Sqlite3::UnbufferedResult.new(self, @conn.prepare(sql))
53
+ Baza::Driver::Sqlite3::UnbufferedResult.new(self, @conn.prepare(sql))
52
54
  end
53
55
 
54
56
  # Escapes a string to be safe to used in a query.
55
57
  def escape(string)
56
- #This code is taken directly from the documentation so we dont have to rely on the SQLite3::Database class. This way it can also be used with JRuby and IronRuby...
57
- #http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html
58
- return string.to_s.gsub(/'/, "''")
58
+ # This code is taken directly from the documentation so we dont have to rely on the SQLite3::Database class. This way it can also be used with JRuby and IronRuby...
59
+ # http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html
60
+ string.to_s.gsub(/'/, "''")
59
61
  end
60
62
 
61
63
  # Returns the last inserted ID.
62
64
  def last_id
63
65
  return @conn.last_insert_row_id if @conn.respond_to?(:last_insert_row_id)
64
- return query("SELECT last_insert_rowid() AS id").fetch[:id].to_i
66
+ query("SELECT last_insert_rowid() AS id").fetch[:id].to_i
65
67
  end
66
68
 
67
69
  # Closes the connection to the database.
data/lib/baza/dump.rb CHANGED
@@ -1,78 +1,78 @@
1
- #This class can be used to make SQL-dumps of databases, tables or however you want it.
1
+ # This class can be used to make SQL-dumps of databases, tables or however you want it.
2
2
  class Baza::Dump
3
- #Constructor.
3
+ # Constructor.
4
4
  #===Examples
5
5
  # dump = Baza::Dump.new(:db => db)
6
6
  def initialize(args)
7
7
  @args = args
8
8
  @debug = @args[:debug]
9
9
  end
10
-
11
- #Method used to update the status.
10
+
11
+ # Method used to update the status.
12
12
  def update_status
13
- return nil if !@on_status
13
+ return nil unless @on_status
14
14
  rows_count = Knj::Locales.number_out(@rows_count, 0)
15
15
  rows_count_total = Knj::Locales.number_out(@rows_count_total, 0)
16
16
  percent = (@rows_count.to_f / @rows_count_total.to_f) * 100
17
17
  percent_text = Knj::Locales.number_out(percent, 1)
18
- @on_status.call(:text => "Dumping table: '#{@table_obj.name}' (#{rows_count}/#{rows_count_total} - #{percent_text}%).")
18
+ @on_status.call(text: "Dumping table: '#{@table_obj.name}' (#{rows_count}/#{rows_count_total} - #{percent_text}%).")
19
19
  end
20
-
21
- #Dumps all tables into the given IO.
20
+
21
+ # Dumps all tables into the given IO.
22
22
  def dump(io)
23
23
  print "Going through tables.\n" if @debug
24
24
  @rows_count = 0
25
-
25
+
26
26
  if @args[:tables]
27
27
  tables = @args[:tables]
28
28
  else
29
- tables = @args[:db].tables.list.values
29
+ tables = @args[:db].tables.list
30
30
  end
31
-
31
+
32
32
  if @on_status
33
- @on_status.call(:text => "Preparing.")
34
-
33
+ @on_status.call(text: "Preparing.")
34
+
35
35
  @rows_count_total = 0
36
36
  tables.each do |table_obj|
37
37
  @rows_count_total += table_obj.rows_count
38
38
  end
39
39
  end
40
-
40
+
41
41
  tables.each do |table_obj|
42
- table_obj = @args[:db].tables[table_obj] if table_obj.is_a?(String) or table_obj.is_a?(Symbol)
42
+ table_obj = @args[:db].tables[table_obj] if table_obj.is_a?(String) || table_obj.is_a?(Symbol)
43
43
  next if table_obj.native?
44
-
45
- #Figure out keys.
44
+
45
+ # Figure out keys.
46
46
  @keys = []
47
47
  table_obj.columns do |col|
48
48
  @keys << col.name
49
49
  end
50
-
50
+
51
51
  @table_obj = table_obj
52
- self.update_status
52
+ update_status
53
53
  puts "Dumping table: '#{table_obj.name}'." if @debug
54
- self.dump_table(io, table_obj)
54
+ dump_table(io, table_obj)
55
55
  end
56
56
  end
57
-
58
- #A block can be executed when a new status occurs.
57
+
58
+ # A block can be executed when a new status occurs.
59
59
  def on_status(&block)
60
60
  @on_status = block
61
61
  end
62
-
63
- #Dumps the given table into the given IO.
62
+
63
+ # Dumps the given table into the given IO.
64
64
  def dump_table(io, table_obj)
65
65
  create_data = table_obj.data
66
66
  create_data.delete(:name)
67
-
68
- #Get SQL for creating table and add it to IO.
69
- sqls = @args[:db].tables.create(table_obj.name, create_data, :return_sql => true)
67
+
68
+ # Get SQL for creating table and add it to IO.
69
+ sqls = @args[:db].tables.create(table_obj.name, create_data, return_sql: true)
70
70
  sqls.each do |sql|
71
71
  io.write("#{sql};\n")
72
72
  end
73
-
74
-
75
- #Try to find a primary column in the table.
73
+
74
+
75
+ # Try to find a primary column in the table.
76
76
  prim_col = nil
77
77
  table_obj.columns do |col|
78
78
  if col.primarykey?
@@ -80,46 +80,46 @@ class Baza::Dump
80
80
  break
81
81
  end
82
82
  end
83
-
84
-
85
- #Set up rows and way to fill rows.
83
+
84
+
85
+ # Set up rows and way to fill rows.
86
86
  rows = []
87
87
  block_data = proc do |row|
88
88
  rows << row
89
89
  @rows_count += 1
90
-
90
+
91
91
  if rows.length >= 1000
92
- self.update_status
93
- self.dump_insert_multi(io, table_obj, rows)
92
+ update_status
93
+ dump_insert_multi(io, table_obj, rows)
94
94
  end
95
95
  end
96
-
97
-
98
- #If a primary column is found then use IDQuery. Otherwise use cloned unbuffered query.
99
- args = {:idquery => prim_col.name.to_sym} if prim_col
100
-
101
-
102
- #Clone the connecting with array-results and execute query.
103
- @args[:db].clone_conn(:result => "array") do |db|
96
+
97
+
98
+ # If a primary column is found then use IDQuery. Otherwise use cloned unbuffered query.
99
+ args = {idquery: prim_col.name} if prim_col
100
+
101
+
102
+ # Clone the connecting with array-results and execute query.
103
+ @args[:db].clone_conn(result: "array") do |db|
104
104
  db.select(table_obj.name, nil, args, &block_data)
105
105
  end
106
-
107
-
108
- #Dump the last rows if any.
109
- self.dump_insert_multi(io, table_obj, rows) if !rows.empty?
106
+
107
+
108
+ # Dump the last rows if any.
109
+ dump_insert_multi(io, table_obj, rows) unless rows.empty?
110
110
  end
111
-
112
- #Dumps the given rows from the given table into the given IO.
111
+
112
+ # Dumps the given rows from the given table into the given IO.
113
113
  def dump_insert_multi(io, table_obj, rows)
114
114
  print "Inserting #{rows.length} into #{table_obj.name}.\n" if @debug
115
- sqls = @args[:db].insert_multi(table_obj.name, rows, :return_sql => true, :keys => @keys)
115
+ sqls = @args[:db].insert_multi(table_obj.name, rows, return_sql: true, keys: @keys)
116
116
  sqls.each do |sql|
117
117
  io.write("#{sql};\n")
118
118
  end
119
-
119
+
120
120
  rows.clear
121
-
122
- #Ensure garbage collection or we might start using A LOT of memory.
121
+
122
+ # Ensure garbage collection or we might start using A LOT of memory.
123
123
  GC.start
124
124
  end
125
- end
125
+ end
data/lib/baza/errors.rb CHANGED
@@ -1,3 +1,8 @@
1
1
  class Baza::Errors
2
+ class DatabaseNotFound < RuntimeError; end
3
+ class ColumnNotFound < RuntimeError; end
4
+ class IndexNotFound < RuntimeError; end
5
+ class NotImplemented < RuntimeError; end
2
6
  class Retry < RuntimeError; end
7
+ class TableNotFound < RuntimeError; end
3
8
  end
data/lib/baza/idquery.rb CHANGED
@@ -1,9 +1,9 @@
1
- #This class takes a lot of IDs and runs a query against them.
1
+ # This class takes a lot of IDs and runs a query against them.
2
2
  class Baza::Idquery
3
- #An array containing all the IDs that will be looked up.
3
+ # An array containing all the IDs that will be looked up.
4
4
  attr_reader :ids
5
5
 
6
- #Constructor.
6
+ # Constructor.
7
7
  #===Examples
8
8
  # idq = Baza::Idquery(db: db, table: :users)
9
9
  # idq.ids + [1, 5, 9]
@@ -17,7 +17,7 @@ class Baza::Idquery
17
17
 
18
18
  if @args[:query]
19
19
  @args[:db].q(@args[:query]) do |data|
20
- @args[:col] = data.keys.first if !@args[:col]
20
+ @args[:col] = data.keys.first unless @args[:col]
21
21
 
22
22
  if data.is_a?(Array)
23
23
  @ids << data.first
@@ -27,59 +27,59 @@ class Baza::Idquery
27
27
  end
28
28
  end
29
29
 
30
- @args[:col] = :id if !@args[:col]
31
- @args[:size] = 200 if !@args[:size]
30
+ @args[:col] = :id unless @args[:col]
31
+ @args[:size] = 200 unless @args[:size]
32
32
 
33
33
  if block
34
- raise "No query was given but a block was." if !@args[:query]
35
- self.each(&block)
34
+ raise "No query was given but a block was." unless @args[:query]
35
+ each(&block)
36
36
  end
37
37
  end
38
38
 
39
- #Fetches results.
39
+ # Fetches results.
40
40
  #===Examples
41
41
  # data = idq.fetch #=> Hash
42
42
  def fetch
43
- return nil if !@args
43
+ return nil unless @args
44
44
 
45
45
  if @res
46
46
  data = @res.fetch if @res
47
- @res = nil if !data
47
+ @res = nil unless data
48
48
  return data if data
49
49
  end
50
50
 
51
- @res = new_res if !@res
52
- if !@res
51
+ @res = new_res unless @res
52
+ unless @res
53
53
  destroy
54
54
  return nil
55
55
  end
56
56
 
57
57
  data = @res.fetch
58
- if !data
58
+ unless data
59
59
  destroy
60
60
  return nil
61
61
  end
62
62
 
63
- return data
63
+ data
64
64
  end
65
65
 
66
- #Yields a block for every result.
66
+ # Yields a block for every result.
67
67
  #===Examples
68
68
  # idq.each do |data|
69
69
  # print "Name: #{data[:name]}\n"
70
70
  # end
71
71
  def each
72
- while data = self.fetch
72
+ while data = fetch
73
73
  yield(data)
74
74
  end
75
75
  end
76
76
 
77
- private
77
+ private
78
78
 
79
- #Spawns a new database-result to read from.
79
+ # Spawns a new database-result to read from.
80
80
  def new_res
81
- table_esc = "`#{@args[:db].esc_table(@args[:table])}`"
82
- col_esc = "`#{@args[:db].esc_col(@args[:col])}`"
81
+ table_esc = "`#{@args[:db].escape_table(@args[:table])}`"
82
+ col_esc = "`#{@args[:db].escape_column(@args[:col])}`"
83
83
  ids = @ids.shift(@args[:size])
84
84
 
85
85
  if ids.empty?
@@ -87,17 +87,17 @@ class Baza::Idquery
87
87
  return nil
88
88
  end
89
89
 
90
- ids_sql = ids.map { |id| "'#{@args[:db].esc(id)}'" }.join(',')
90
+ ids_sql = ids.map { |id| "'#{@args[:db].esc(id)}'" }.join(",")
91
91
  query_str = "SELECT * FROM #{table_esc} WHERE #{table_esc}.#{col_esc} IN (#{ids_sql})"
92
92
  print "Query: #{query_str}\n" if @debug
93
93
 
94
- return @args[:db].q(query_str)
94
+ @args[:db].q(query_str)
95
95
  end
96
96
 
97
- #Removes all variables on the object. This is done when no more results are available.
97
+ # Removes all variables on the object. This is done when no more results are available.
98
98
  def destroy
99
99
  @args = nil
100
100
  @ids = nil
101
101
  @debug = nil
102
102
  end
103
- end
103
+ end
data/lib/baza/index.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  class Baza::Index
2
+ include Baza::DatabaseModelFunctionality
3
+
2
4
  def to_s
3
5
  "#<#{self.class.name} name: \"#{name}\" unique=\"#{unique?}\" columns: #{@columns}>"
4
6
  end
@@ -6,4 +8,8 @@ class Baza::Index
6
8
  def inspect
7
9
  to_s
8
10
  end
11
+
12
+ def to_param
13
+ name
14
+ end
9
15
  end
@@ -81,7 +81,7 @@ private
81
81
  stmt.close if stmt
82
82
  @java_rs_data.delete(id) if result && id
83
83
 
84
- if e.message == 'query does not return ResultSet'
84
+ if e.message == "query does not return ResultSet"
85
85
  return query_no_result_set(sql)
86
86
  else
87
87
  raise e
@@ -91,12 +91,10 @@ private
91
91
  end
92
92
 
93
93
  def query_no_result_set(sql)
94
- begin
95
- stmt = @conn.create_statement
96
- stmt.execute(sql)
97
- return nil
98
- ensure
99
- stmt.close if stmt
100
- end
94
+ stmt = @conn.create_statement
95
+ stmt.execute(sql)
96
+ return nil
97
+ ensure
98
+ stmt.close if stmt
101
99
  end
102
100
  end
@@ -96,7 +96,7 @@ private
96
96
  hash[@keys[count]] = value
97
97
  end
98
98
 
99
- return hash
99
+ hash
100
100
  end
101
101
 
102
102
  def translate_type(result, count)