Class: Exwiw::Adapter::Sqlite3Adapter
- Defined in:
- lib/exwiw/adapter/sqlite3_adapter.rb
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
- #build_query(table, dump_target, table_by_name) ⇒ Object
- #compile_ast(query_ast) ⇒ Object
- #dump_schema(ordered_tables, output_path) ⇒ Object
- #execute(query_ast) ⇒ Object
- #to_bulk_delete(select_query_ast, table) ⇒ Object
- #to_bulk_insert(results, table) ⇒ Object
Methods inherited from Base
#dumpable?, #initialize, #output_extension, #post_insert_sql, #schema_output_extension, #supports_bulk_delete?, table_config_class, #validate_as_dump_target!
Constructor Details
This class inherits a constructor from Exwiw::Adapter::Base
Instance Method Details
#build_query(table, dump_target, table_by_name) ⇒ Object
6 7 8 |
# File 'lib/exwiw/adapter/sqlite3_adapter.rb', line 6 def build_query(table, dump_target, table_by_name) Exwiw::QueryAstBuilder.run(table.name, table_by_name, dump_target, @logger) end |
#compile_ast(query_ast) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/exwiw/adapter/sqlite3_adapter.rb', line 119 def compile_ast(query_ast) raise NotImplementedError unless query_ast.is_a?(Exwiw::QueryAst::Select) sql = "SELECT " sql += query_ast.columns.map { |col| compile_column_name(query_ast, col) }.join(', ') sql += " FROM #{query_ast.from_table_name}" query_ast.join_clauses.each do |join| sql += " JOIN #{join.join_table_name} ON #{join.base_table_name}.#{join.foreign_key} = #{join.join_table_name}.#{join.primary_key}" join.where_clauses.each do |where| compiled_where_condition = compile_where_condition(where, join.join_table_name) sql += " AND #{compiled_where_condition}" end end if query_ast.where_clauses.any? sql += " WHERE " sql += query_ast.where_clauses.map { |where| compile_where_condition(where, query_ast.from_table_name) }.join(' AND ') end sql end |
#dump_schema(ordered_tables, output_path) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/exwiw/adapter/sqlite3_adapter.rb', line 17 def dump_schema(ordered_tables, output_path) @logger.debug(" Reading schema from sqlite_master...") target_names = ordered_tables.map(&:name) # `sqlite_master` row order preserves table creation order, which is also # the dependency order produced by ActiveRecord-style migrations. To respect # the caller-provided order, we partition tables / their owned indexes by # ordered_tables. all = connection.execute(<<~SQL) SELECT type, name, tbl_name, sql FROM sqlite_master WHERE sql IS NOT NULL AND name NOT LIKE 'sqlite_%' SQL tables_by_name = all.select { |type, _, _, _| type == 'table' }.to_h { |_, name, _, sql| [name, sql] } indexes_by_owner = all.select { |type, _, _, _| type == 'index' }.group_by { |_, _, tbl, _| tbl } triggers_by_owner = all.select { |type, _, _, _| type == 'trigger' }.group_by { |_, _, tbl, _| tbl } statements = [] target_names.each do |name| table_sql = tables_by_name[name] next unless table_sql statements << finalize_stmt(DdlPostprocessor.add_if_not_exists_to_create_table(table_sql.strip)) (indexes_by_owner[name] || []).each do |_, _, _, idx_sql| statements << finalize_stmt(DdlPostprocessor.add_if_not_exists_to_create_index(idx_sql.strip)) end (triggers_by_owner[name] || []).each do |_, _, _, trg_sql| statements << finalize_stmt(trg_sql.strip) end end File.open(output_path, 'w') do |file| file.puts("-- Auto-generated by exwiw. Idempotent CREATE statements for sqlite3.") file.puts(statements.join("\n")) end @logger.info(" Wrote #{statements.size} schema statement(s) to #{output_path}.") end |
#execute(query_ast) ⇒ Object
10 11 12 13 14 15 |
# File 'lib/exwiw/adapter/sqlite3_adapter.rb', line 10 def execute(query_ast) sql = compile_ast(query_ast) @logger.debug(" Executing SQL: \n#{sql}") connection.execute(sql) end |
#to_bulk_delete(select_query_ast, table) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/exwiw/adapter/sqlite3_adapter.rb', line 73 def to_bulk_delete(select_query_ast, table) raise NotImplementedError unless select_query_ast.is_a?(Exwiw::QueryAst::Select) sql = "DELETE FROM #{select_query_ast.from_table_name}" if select_query_ast.join_clauses.empty? # Ignore filter option, because bulk delete is for cleaning before import, # so it should delete all records to avoid foreign key violation & data consistancy. compiled_where_conditions = select_query_ast. where_clauses. select { |where| where.is_a?(Exwiw::QueryAst::WhereClause) }. map do |where| compile_where_condition(where, select_query_ast.from_table_name) end if compiled_where_conditions.size > 0 sql += "\nWHERE " sql += compiled_where_conditions.join(' AND ') end sql += ";" return sql end subquery_ast = Exwiw::QueryAst::Select.new first_join = select_query_ast.join_clauses.first.clone subquery_ast.from(first_join.join_table_name) primay_key_col = table.columns.find { |col| col.name == table.primary_key } subquery_ast.select([primay_key_col]) select_query_ast.join_clauses[1..].each do |join| subquery_ast.join(join) end first_join.where_clauses.each do |where| # Ignore filter option, because bulk delete is for cleaning before import, # so it should delete all records to avoid foreign key violation & data consistancy. subquery_ast.where(where) if where.is_a?(Exwiw::QueryAst::WhereClause) end foreign_key = first_join.foreign_key subquery_sql = compile_ast(subquery_ast) sql += "\nWHERE #{select_query_ast.from_table_name}.#{foreign_key} IN (#{subquery_sql});" sql end |
#to_bulk_insert(results, table) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/exwiw/adapter/sqlite3_adapter.rb', line 58 def to_bulk_insert(results, table) table_name = table.name value_list = results.map do |row| quoted_values = row.map do |value| escape_value(value) end "(" + quoted_values.join(', ') + ")" end values = value_list.join(",\n") column_names = table.columns.map(&:name).join(', ') "INSERT INTO #{table_name} (#{column_names}) VALUES\n#{values};" end |