Module: Export::Project
- Defined in:
- lib/export/project.rb
Class Method Summary collapse
- .download(project) ⇒ Object
- .dump_table(table, io, project_id) ⇒ Object private
- .export_users(io, project) ⇒ Object private
-
.generate_dump(project, file) ⇒ Object
Restorable with psql -U :username -d :database -f dump.sql.
Class Method Details
.download(project) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/export/project.rb', line 30 def self.download(project) Tempfile.create do |file| buffer = ::Zip::OutputStream.write_buffer(file) do |zipfile| zipfile.put_next_entry('dump.sql') generate_dump(project, zipfile) end buffer.flush Download.create!( name: "#{project.name} export on #{Time.now}.", description: 'A zip file containing SQL dump of community data + project-specific data', filename: Zaru::sanitize!("#{project.name}.zip").gsub(' ', '_').downcase, source_file_path: file.path, expires: 2.days.from_now, is_public: false ) end end |
.dump_table(table, io, project_id) ⇒ Object (private)
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/export/project.rb', line 50 def self.dump_table(table, io, project_id) conn = ActiveRecord::Base.connection.raw_connection cols = ActiveRecord::Base.connection.columns(table).map { |c| "\"#{c.name}\"" } if cols.include?('"project_id"') where_clause = "WHERE project_id = #{project_id}" elsif table == 'projects' where_clause = "WHERE id = #{project_id}" else where_clause = '' end io.puts("COPY public.#{table} (#{cols.join(', ')}) FROM stdin;") # TODO: Consider "WITH CSV HEADER" if dumping to a set of CSV files gets implemented conn.copy_data("COPY (SELECT #{cols.join(', ')} FROM #{table} #{where_clause}) TO STDOUT") do while row = conn.get_copy_data io.write(row) end end io.puts('\.') io.puts io.write("SELECT setval('public.#{table}_id_seq', (SELECT MAX(id) FROM public.#{table}));\n\n") if cols.include?('"id"') end |
.export_users(io, project) ⇒ Object (private)
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 |
# File 'lib/export/project.rb', line 76 def self.export_users(io, project) members = project.users.all conn = ActiveRecord::Base.connection.raw_connection User.all.each do |user| attributes = { id: user.id, password_digest: "'#{conn.escape_string(User.new(password: 'taxonworks').password_digest)}'", created_at: "'#{user.created_at}'", updated_at: "'#{user.updated_at}'", created_by_id: user.created_by_id || 'NULL', updated_by_id: user.updated_by_id || 'NULL', is_administrator: user.is_administrator || 'NULL', hub_tab_order: "'{#{conn.escape_string(user.hub_tab_order.join(','))}}'" }.merge!( if members.include?(user) { email: "'#{conn.escape_string(user.email)}'", name: "'#{conn.escape_string(user.name)}'" } else { email: "'unknown_#{user.id}@example.com'", name: "'User outside project (#{user.id})'" } end ) io.puts("INSERT INTO public.users(#{attributes.keys.join(', ')})\nVALUES (#{attributes.values.join(', ')});") end io.puts end |
.generate_dump(project, file) ⇒ Object
Restorable with psql -U :username -d :database -f dump.sql. Requires database to be created without tables (rails db:create)
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/export/project.rb', line 4 def self.generate_dump(project, file) config = ActiveRecord::Base.connection_config args = [ ['-h', config[:host]], ['-s', config[:database]], ['-U', config[:username]], ['-p', config[:port]] ].reject! { |(a, v)| v.nil? }.flatten! # Retrieve schema schema = Open3.capture3({'PGPASSWORD' => config[:password]}, 'pg_dump', '-w', '-O', *args).first # Open gap to insert COPY statements (between tables creation and contraints & indices setup) split_point = schema.index(/\n(--[^\n]*\n)*\s*ALTER\s+TABLE/) schema_head, schema_tail = schema[0..split_point-1], schema[split_point..-1] tables = (ActiveRecord::Base.connection.tables - ['spatial_ref_sys', 'project', 'users', 'versions']).sort file.puts schema_head file.write "\n-- DATA RESTORE\n\n" export_users(file, project) tables.each { |t| dump_table(t, file, project.id) } file.puts schema_tail end |