Class: Databasium::Schema

Inherits:
Object
  • Object
show all
Defined in:
app/services/databasium/schema.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSchema

Returns a new instance of Schema.



3
4
5
6
7
# File 'app/services/databasium/schema.rb', line 3

def initialize
  @conn = ActiveRecord::Base.connection
  @tables = @conn.data_sources - %w[ar_internal_metadata schema_migrations]
  @schema = nil
end

Instance Attribute Details

#schemaObject (readonly)

Returns the value of attribute schema.



2
3
4
# File 'app/services/databasium/schema.rb', line 2

def schema
  @schema
end

#tablesObject (readonly)

Returns the value of attribute tables.



2
3
4
# File 'app/services/databasium/schema.rb', line 2

def tables
  @tables
end

Instance Method Details

#get_associations(table) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'app/services/databasium/schema.rb', line 15

def get_associations(table)
  model =
    ActiveRecord::Base.descendants.find { |m| m.table_name == table } ||
      table.classify.safe_constantize
  if model
    model.reflect_on_all_associations.map do |r|
      {
        name: r.name.to_s.pluralize,
        macro: r.macro,
        class_name: r.class_name,
        foreign_key: r.foreign_key
      }
    end
  else
    []
  end
end

#get_columns(model) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/services/databasium/schema.rb', line 87

def get_columns(model)
  return if model.nil?
  model.columns.map do |column|
    {
      name: column.name,
      type: column.type.to_s,
      used: false,
      foreign_key: is_column_foreign_key?(model.table_name, column.name),
      to_table: get_foreign_key_to_table(model.table_name, column.name)
    }
  end
end

#get_columns_from_table(table) ⇒ Object



72
73
74
75
76
# File 'app/services/databasium/schema.rb', line 72

def get_columns_from_table(table)
  @conn
    .columns(table)
    .map { |c| { name: c.name, sql_type: c.sql_type, null: c.null, default: c.default } }
end

#get_columns_names(table) ⇒ Object



78
79
80
# File 'app/services/databasium/schema.rb', line 78

def get_columns_names(table)
  @conn.columns(table_name_for(table)).map { |c| c.name }
end

#get_foreign_keys(table) ⇒ Object



64
65
66
67
68
69
70
# File 'app/services/databasium/schema.rb', line 64

def get_foreign_keys(table)
  @conn
    .foreign_keys(table)
    .map do |fk|
      { from: fk.from_table, to: fk.to_table, column: fk.column, primary_key: fk.primary_key }
    end
end

#get_model_and_layers_BFS(model, layers) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'app/services/databasium/schema.rb', line 44

def get_model_and_layers_BFS(model, layers)
  queue = Queue.new()
  queue.push([ table_name_for(model), 0 ])
  result = {}

  until queue.empty?
    table, layer = queue.pop
    next if (layers.present? && layer > layers) || result[table].present?
    result[table] = get_schema_for_model(table)

    model_associations = result[table].fetch("associations", nil)
    model_associations&.each { |a| queue << [ a["name"], layer + 1 ] }
  end
  result
end

#get_model_from_table(table) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'app/services/databasium/schema.rb', line 100

def get_model_from_table(table)
  return nil, "Select a table to view its records." if table.nil?
  table_name = table_name_for(table)
  unless ActiveRecord::Base.connection.table_exists?(table_name)
    return nil, "Table #{table} does not exist"
  end
  begin
    # If there is no model for this table it will raise a NameError
    @model =
      ActiveRecord::Base.descendants.find { |model| model.table_name == table_name } ||
        table_name.classify.constantize
    @error = nil
  rescue NameError
    @model = nil
    @error =
      "No model found for this table,
      if you would like to interact with this table, you need to create a model for it."
  end
  [ @model, @error ]
end

#get_schema_for_model(model) ⇒ Object



60
61
62
# File 'app/services/databasium/schema.rb', line 60

def get_schema_for_model(model)
  schema[table_name_for(model)]
end

#get_tables(search) ⇒ Object



82
83
84
85
# File 'app/services/databasium/schema.rb', line 82

def get_tables(search)
  @tables = @tables.select { |table| table =~ /#{search}/i } if search
  @tables
end

#sync!(schema: nil) ⇒ Object



9
10
11
12
13
# File 'app/services/databasium/schema.rb', line 9

def sync!(schema: nil)
  path = Rails.root.join("storage")
  FileUtils.mkdir_p(path) unless Dir.exist?(path)
  File.write(path.join("schema_graph.json"), schema || build_schema.to_json)
end