Guest User

Untitled

a guest
Jul 28th, 2018
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.18 KB | None | 0 0
  1. require 'rubygems'
  2. require 'sequel'
  3. require 'rgl/adjacency'
  4. require 'rgl/topsort'
  5. require 'rgl/transitiv_closure'
  6. require 'rgl/connected_components'
  7.  
  8. # Usage example below
  9.  
  10. class DatabaseEmptier
  11. def initialize(information_schema_db, options = {})
  12. @information_schema_db = information_schema_db
  13. @tables_to_preserve = (options[:preserve] || [ ]).map { |table_name| table_name.to_sym }
  14. end
  15.  
  16. def to_ruby
  17. statements { |table_name|
  18. "Sequel::Model.db[#{table_name.inspect}].delete"
  19. }
  20. end
  21.  
  22. def to_sql
  23. statements { |table_name|
  24. "DELETE FROM #{table_name};"
  25. }
  26. end
  27.  
  28. private
  29.  
  30. def statements(&block)
  31. tables_ordered_for_deletion.map(&block).join("\n")
  32. end
  33.  
  34. def tables_to_empty
  35. db_tables - @tables_to_preserve
  36. end
  37.  
  38. def db_tables
  39. @information_schema_db[:TABLES].
  40. select(:TABLE_NAME).
  41. filter(:TABLE_SCHEMA => TARGET_DATABASE).
  42. map(:TABLE_NAME).
  43. map { |table_name| table_name.to_sym }
  44. end
  45.  
  46. def constraint_graph
  47. constraint_graph = RGL::DirectedAdjacencyGraph.new
  48. db_constraints.each do |constraint|
  49. from = constraint[:TABLE_NAME].to_sym
  50. to = constraint[:REFERENCED_TABLE_NAME].to_sym
  51. # RGL won't generate a complete topological sort if the graph contains cycles.
  52. # The condition here eliminates cycles from self-referential tables
  53. constraint_graph.add_edge(from, to) unless from == to
  54. end
  55.  
  56. puts "Cycles detected in graph - output statements will be incomplete" unless constraint_graph.acyclic?
  57.  
  58. constraint_graph
  59. end
  60.  
  61. def db_constraints
  62. @information_schema_db[:REFERENTIAL_CONSTRAINTS].
  63. select(:TABLE_NAME, :REFERENCED_TABLE_NAME).
  64. filter(:CONSTRAINT_SCHEMA => TARGET_DATABASE)
  65. end
  66.  
  67. def isolated_tables
  68. tables_to_empty - constraint_graph.vertices
  69. end
  70.  
  71. def tables_ordered_for_deletion
  72. constraint_graph.topsort_iterator.to_a + isolated_tables
  73. end
  74. end
  75.  
  76. TARGET_DATABASE = 'db_to_empty'
  77. USERNAME = 'username'
  78. PASSWORD = 'password'
  79.  
  80. db = Sequel.connect("mysql://localhost/information_schema?user=#{USERNAME}&password=#{PASSWORD}")
  81. db_emptier = DatabaseEmptier.new(db, :preserve => ["schema_info"])
  82. puts db_emptier.to_ruby
  83. puts db_emptier.to_sql
Add Comment
Please, Sign In to add comment