Introduced foreign keys to ensure consistent data state.

This commit is contained in:
Thorsten Eckel 2017-06-06 17:49:49 +02:00
parent 278e90fc63
commit cb919312b0
13 changed files with 511 additions and 204 deletions

View file

@ -12,7 +12,7 @@ class EmailAddress < ApplicationModel
before_update :check_if_channel_exists_set_inactive
after_create :update_email_address_id
after_update :update_email_address_id
after_destroy :delete_group_reference
before_destroy :delete_group_reference
=begin
@ -59,7 +59,7 @@ check and if channel not exists reset configured channels for email addresses
# delete group.email_address_id reference if email address get's deleted
def delete_group_reference
Group.where(email_address_id: id).each { |group|
group.email_address_id = nil
group.update_attributes!(email_address_id: nil)
}
end

View file

@ -5,17 +5,9 @@ class History < ApplicationModel
include History::Assets
self.table_name = 'histories'
belongs_to :history_type, class_name: 'History::Type'
belongs_to :history_object, class_name: 'History::Object'
belongs_to :history_attribute, class_name: 'History::Attribute'
# before_validation :check_type, :check_object
# attr_writer :history_type, :history_object
# rubocop:disable Style/ClassVars
@@cache_type = {}
@@cache_object = {}
@@cache_attribute = {}
# rubocop:enable Style/ClassVars
belongs_to :history_type, class_name: 'History::Type'
belongs_to :history_object, class_name: 'History::Object'
belongs_to :history_attribute, class_name: 'History::Attribute'
=begin
@ -216,96 +208,54 @@ returns
end
def self.type_lookup_id(id)
# use cache
return @@cache_type[ id ] if @@cache_type[ id ]
# lookup
history_type = History::Type.lookup(id: id)
@@cache_type[ id ] = history_type
history_type
History::Type.lookup(id: id)
end
def self.type_lookup(name)
# use cache
return @@cache_type[ name ] if @@cache_type[ name ]
# lookup
history_type = History::Type.lookup(name: name)
if history_type
@@cache_type[ name ] = history_type
return history_type
end
# create
history_type = History::Type.create(
History::Type.create(
name: name
)
@@cache_type[ name ] = history_type
history_type
end
def self.object_lookup_id(id)
# use cache
return @@cache_object[ id ] if @@cache_object[ id ]
# lookup
history_object = History::Object.lookup(id: id)
@@cache_object[ id ] = history_object
history_object
History::Object.lookup(id: id)
end
def self.object_lookup(name)
# use cache
return @@cache_object[ name ] if @@cache_object[ name ]
# lookup
history_object = History::Object.lookup(name: name)
if history_object
@@cache_object[ name ] = history_object
return history_object
end
# create
history_object = History::Object.create(
History::Object.create(
name: name
)
@@cache_object[ name ] = history_object
history_object
end
def self.attribute_lookup_id(id)
# use cache
return @@cache_attribute[ id ] if @@cache_attribute[ id ]
# lookup
history_attribute = History::Attribute.lookup(id: id)
@@cache_attribute[ id ] = history_attribute
history_attribute
History::Attribute.lookup(id: id)
end
def self.attribute_lookup(name)
# use cache
return @@cache_attribute[ name ] if @@cache_attribute[ name ]
# lookup
history_attribute = History::Attribute.lookup(name: name)
if history_attribute
@@cache_attribute[ name ] = history_attribute
return history_attribute
end
# create
history_attribute = History::Attribute.create(
History::Attribute.create(
name: name
)
@@cache_attribute[ name ] = history_attribute
history_attribute
end
class Object < ApplicationModel

View file

@ -1,35 +1,23 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ObjectLookup < ApplicationModel
@@cache_object = {} # rubocop:disable Style/ClassVars
def self.by_id(id)
# use cache
return @@cache_object[ id ] if @@cache_object[ id ]
# lookup
lookup = self.lookup(id: id)
return if !lookup
@@cache_object[ id ] = lookup.name
lookup.name
end
def self.by_name(name)
# use cache
return @@cache_object[ name ] if @@cache_object[ name ]
# lookup
lookup = self.lookup(name: name)
if lookup
@@cache_object[ name ] = lookup.id
return lookup.id
end
# create
lookup = create(name: name)
@@cache_object[ name ] = lookup.id
lookup.id
end

View file

@ -118,25 +118,22 @@ returns
remove one attachment from storage
result = Store.remove_item(store_id)
returns
result = true
Store.remove_item(store_id)
=end
def self.remove_item(store_id)
# check backend for references
store = Store.find(store_id)
files = Store.where(store_file_id: store.store_file_id)
if files.count == 1 && files.first.id == store.id
Store::File.find(store.store_file_id).destroy
end
store = Store.find(store_id)
file_id = store.store_file_id
store.destroy
true
# check backend for references
files = Store.where(store_file_id: file_id)
return if files.count != 1
return if files.first.id != store.id
Store::File.find(file_id).destroy
end
=begin

View file

@ -1,29 +1,17 @@
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class TypeLookup < ApplicationModel
@@cache_object = {} # rubocop:disable Style/ClassVars
def self.by_id( id )
# use cache
return @@cache_object[ id ] if @@cache_object[ id ]
# lookup
lookup = self.lookup( id: id )
return if !lookup
@@cache_object[ id ] = lookup.name
lookup.name
end
def self.by_name( name )
# use cache
return @@cache_object[ name ] if @@cache_object[ name ]
# lookup
lookup = self.lookup( name: name )
if lookup
@@cache_object[ name ] = lookup.id
return lookup.id
end
@ -31,8 +19,6 @@ class TypeLookup < ApplicationModel
lookup = create(
name: name
)
@@cache_object[ name ] = lookup.id
lookup.id
end
end

View file

@ -56,6 +56,8 @@ class CreateBase < ActiveRecord::Migration
add_index :users, [:mobile]
add_index :users, [:source]
add_index :users, [:created_by_id]
add_foreign_key :users, :users, column: :created_by_id
add_foreign_key :users, :users, column: :updated_by_id
create_table :signatures do |t|
t.string :name, limit: 100, null: false
@ -67,6 +69,8 @@ class CreateBase < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :signatures, [:name], unique: true
add_foreign_key :signatures, :users, column: :created_by_id
add_foreign_key :signatures, :users, column: :updated_by_id
create_table :email_addresses do |t|
t.integer :channel_id, null: true
@ -80,6 +84,8 @@ class CreateBase < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :email_addresses, [:email], unique: true
add_foreign_key :email_addresses, :users, column: :created_by_id
add_foreign_key :email_addresses, :users, column: :updated_by_id
create_table :groups do |t|
t.references :signature, null: true
@ -95,6 +101,10 @@ class CreateBase < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :groups, [:name], unique: true
add_foreign_key :groups, :signatures
add_foreign_key :groups, :email_addresses
add_foreign_key :groups, :users, column: :created_by_id
add_foreign_key :groups, :users, column: :updated_by_id
create_table :roles do |t|
t.string :name, limit: 100, null: false
@ -107,6 +117,8 @@ class CreateBase < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :roles, [:name], unique: true
add_foreign_key :roles, :users, column: :created_by_id
add_foreign_key :roles, :users, column: :updated_by_id
create_table :permissions do |t|
t.string :name, limit: 255, null: false
@ -135,27 +147,36 @@ class CreateBase < ActiveRecord::Migration
end
add_index :organizations, [:name], unique: true
add_index :organizations, [:domain]
add_foreign_key :users, :organizations
add_foreign_key :organizations, :users, column: :created_by_id
add_foreign_key :organizations, :users, column: :updated_by_id
create_table :roles_users, id: false do |t|
t.integer :user_id
t.integer :role_id
t.references :user
t.references :role
end
add_index :roles_users, [:user_id]
add_index :roles_users, [:role_id]
add_foreign_key :roles_users, :users
add_foreign_key :roles_users, :roles
create_table :groups_users, id: false do |t|
t.integer :user_id
t.integer :group_id
t.references :user
t.references :group
end
add_index :groups_users, [:user_id]
add_index :groups_users, [:group_id]
add_foreign_key :groups_users, :users
add_foreign_key :groups_users, :groups
create_table :organizations_users, id: false do |t|
t.integer :user_id
t.integer :organization_id
t.references :user
t.references :organization
end
add_index :organizations_users, [:user_id]
add_index :organizations_users, [:organization_id]
add_foreign_key :organizations_users, :users
add_foreign_key :organizations_users, :organizations
create_table :authorizations do |t|
t.string :provider, limit: 250, null: false
@ -169,6 +190,7 @@ class CreateBase < ActiveRecord::Migration
add_index :authorizations, [:uid, :provider]
add_index :authorizations, [:user_id]
add_index :authorizations, [:username]
add_foreign_key :authorizations, :users
create_table :locales do |t|
t.string :locale, limit: 20, null: false
@ -192,6 +214,8 @@ class CreateBase < ActiveRecord::Migration
end
add_index :translations, [:source], length: 255
add_index :translations, [:locale]
add_foreign_key :translations, :users, column: :created_by_id
add_foreign_key :translations, :users, column: :updated_by_id
create_table :object_lookups do |t|
t.string :name, limit: 250, null: false
@ -220,6 +244,7 @@ class CreateBase < ActiveRecord::Migration
add_index :tokens, [:name, :action], unique: true
add_index :tokens, :created_at
add_index :tokens, :persistent
add_foreign_key :tokens, :users
create_table :packages do |t|
t.string :name, limit: 250, null: false
@ -230,6 +255,9 @@ class CreateBase < ActiveRecord::Migration
t.integer :created_by_id, null: false
t.timestamps limit: 3, null: false
end
add_foreign_key :packages, :users, column: :created_by_id
add_foreign_key :packages, :users, column: :updated_by_id
create_table :package_migrations do |t|
t.string :name, limit: 250, null: false
t.string :version, limit: 250, null: false
@ -237,7 +265,7 @@ class CreateBase < ActiveRecord::Migration
end
create_table :taskbars do |t|
t.integer :user_id, null: false
t.references :user, null: false
t.datetime :last_contact, null: false
t.string :client_id, null: false
t.string :key, limit: 100, null: false
@ -253,16 +281,7 @@ class CreateBase < ActiveRecord::Migration
add_index :taskbars, [:user_id]
add_index :taskbars, [:client_id]
add_index :taskbars, [:key]
create_table :tags do |t|
t.references :tag_item, null: false
t.references :tag_object, null: false
t.integer :o_id, null: false
t.integer :created_by_id, null: false
t.timestamps limit: 3, null: false
end
add_index :tags, [:o_id]
add_index :tags, [:tag_object_id]
add_foreign_key :taskbars, :users
create_table :tag_objects do |t|
t.string :name, limit: 250, null: false
@ -277,6 +296,19 @@ class CreateBase < ActiveRecord::Migration
end
add_index :tag_items, [:name_downcase]
create_table :tags do |t|
t.references :tag_item, null: false
t.references :tag_object, null: false
t.integer :o_id, null: false
t.integer :created_by_id, null: false
t.timestamps limit: 3, null: false
end
add_index :tags, [:o_id]
add_index :tags, [:tag_object_id]
add_foreign_key :tags, :tag_items
add_foreign_key :tags, :tag_objects
add_foreign_key :tags, :users, column: :created_by_id
create_table :recent_views do |t|
t.references :recent_view_object, null: false
t.integer :o_id, null: false
@ -287,6 +319,8 @@ class CreateBase < ActiveRecord::Migration
add_index :recent_views, [:created_by_id]
add_index :recent_views, [:created_at]
add_index :recent_views, [:recent_view_object_id]
add_foreign_key :recent_views, :object_lookups, column: :recent_view_object_id
add_foreign_key :recent_views, :users, column: :created_by_id
create_table :activity_streams do |t|
t.references :activity_stream_type, null: false
@ -304,6 +338,30 @@ class CreateBase < ActiveRecord::Migration
add_index :activity_streams, [:created_at]
add_index :activity_streams, [:activity_stream_object_id]
add_index :activity_streams, [:activity_stream_type_id]
add_foreign_key :activity_streams, :type_lookups, column: :activity_stream_type_id
add_foreign_key :activity_streams, :object_lookups, column: :activity_stream_object_id
add_foreign_key :activity_streams, :permissions
add_foreign_key :activity_streams, :groups
add_foreign_key :activity_streams, :users, column: :created_by_id
create_table :history_types do |t|
t.string :name, limit: 250, null: false
t.timestamps limit: 3, null: false
end
add_index :history_types, [:name], unique: true
create_table :history_objects do |t|
t.string :name, limit: 250, null: false
t.string :note, limit: 250, null: true
t.timestamps limit: 3, null: false
end
add_index :history_objects, [:name], unique: true
create_table :history_attributes do |t|
t.string :name, limit: 250, null: false
t.timestamps limit: 3, null: false
end
add_index :history_attributes, [:name], unique: true
create_table :histories do |t|
t.references :history_type, null: false
@ -329,25 +387,10 @@ class CreateBase < ActiveRecord::Migration
add_index :histories, [:id_from]
add_index :histories, [:value_from], length: 255
add_index :histories, [:value_to], length: 255
create_table :history_types do |t|
t.string :name, limit: 250, null: false
t.timestamps limit: 3, null: false
end
add_index :history_types, [:name], unique: true
create_table :history_objects do |t|
t.string :name, limit: 250, null: false
t.string :note, limit: 250, null: true
t.timestamps limit: 3, null: false
end
add_index :history_objects, [:name], unique: true
create_table :history_attributes do |t|
t.string :name, limit: 250, null: false
t.timestamps limit: 3, null: false
end
add_index :history_attributes, [:name], unique: true
add_foreign_key :histories, :history_types
add_foreign_key :histories, :history_objects
add_foreign_key :histories, :history_attributes
add_foreign_key :histories, :users, column: :created_by_id
create_table :settings do |t|
t.string :title, limit: 200, null: false
@ -365,18 +408,6 @@ class CreateBase < ActiveRecord::Migration
add_index :settings, [:area]
add_index :settings, [:frontend]
create_table :stores do |t|
t.references :store_object, null: false
t.references :store_file, null: false
t.integer :o_id, limit: 8, null: false
t.string :preferences, limit: 2500, null: true
t.string :size, limit: 50, null: true
t.string :filename, limit: 250, null: false
t.integer :created_by_id, null: false
t.timestamps limit: 3, null: false
end
add_index :stores, [:store_object_id, :o_id]
create_table :store_objects do |t|
t.string :name, limit: 250, null: false
t.string :note, limit: 250, null: true
@ -392,6 +423,21 @@ class CreateBase < ActiveRecord::Migration
add_index :store_files, [:sha], unique: true
add_index :store_files, [:provider]
create_table :stores do |t|
t.references :store_object, null: false
t.references :store_file, null: false
t.integer :o_id, limit: 8, null: false
t.string :preferences, limit: 2500, null: true
t.string :size, limit: 50, null: true
t.string :filename, limit: 250, null: false
t.integer :created_by_id, null: false
t.timestamps limit: 3, null: false
end
add_index :stores, [:store_object_id, :o_id]
add_foreign_key :stores, :store_objects
add_foreign_key :stores, :store_files
add_foreign_key :stores, :users, column: :created_by_id
create_table :store_provider_dbs do |t|
t.string :sha, limit: 128, null: false
t.binary :data, limit: 200.megabytes, null: true
@ -418,6 +464,8 @@ class CreateBase < ActiveRecord::Migration
add_index :avatars, [:store_hash]
add_index :avatars, [:source]
add_index :avatars, [:default]
add_foreign_key :avatars, :users, column: :created_by_id
add_foreign_key :avatars, :users, column: :updated_by_id
create_table :online_notifications do |t|
t.integer :o_id, null: false
@ -433,6 +481,8 @@ class CreateBase < ActiveRecord::Migration
add_index :online_notifications, [:seen]
add_index :online_notifications, [:created_at]
add_index :online_notifications, [:updated_at]
add_foreign_key :online_notifications, :users, column: :created_by_id
add_foreign_key :online_notifications, :users, column: :updated_by_id
create_table :schedulers do |t|
t.string :name, limit: 250, null: false
@ -449,6 +499,8 @@ class CreateBase < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :schedulers, [:name], unique: true
add_foreign_key :schedulers, :users, column: :created_by_id
add_foreign_key :schedulers, :users, column: :updated_by_id
create_table :calendars do |t|
t.string :name, limit: 250, null: true
@ -464,6 +516,8 @@ class CreateBase < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :calendars, [:name], unique: true
add_foreign_key :calendars, :users, column: :created_by_id
add_foreign_key :calendars, :users, column: :updated_by_id
create_table :user_devices do |t|
t.references :user, null: false
@ -483,6 +537,7 @@ class CreateBase < ActiveRecord::Migration
add_index :user_devices, [:fingerprint]
add_index :user_devices, [:updated_at]
add_index :user_devices, [:created_at]
add_foreign_key :user_devices, :users
create_table :external_credentials do |t|
t.string :name
@ -511,6 +566,9 @@ class CreateBase < ActiveRecord::Migration
end
add_index :object_manager_attributes, [:object_lookup_id, :name], unique: true
add_index :object_manager_attributes, [:object_lookup_id]
add_foreign_key :object_manager_attributes, :object_lookups
add_foreign_key :object_manager_attributes, :users, column: :created_by_id
add_foreign_key :object_manager_attributes, :users, column: :updated_by_id
create_table :delayed_jobs, force: true do |t|
t.integer :priority, default: 0 # Allows some jobs to jump to the front of the queue
@ -573,19 +631,20 @@ class CreateBase < ActiveRecord::Migration
add_index :cti_logs, [:from]
create_table :cti_caller_ids do |t|
t.string :caller_id, limit: 100, null: false
t.string :comment, limit: 500, null: true
t.string :level, limit: 100, null: false
t.string :object, limit: 100, null: false
t.integer :o_id, null: false
t.integer :user_id, null: true
t.text :preferences, limit: 500.kilobytes + 1, null: true
t.string :caller_id, limit: 100, null: false
t.string :comment, limit: 500, null: true
t.string :level, limit: 100, null: false
t.string :object, limit: 100, null: false
t.integer :o_id, null: false
t.references :user, null: true
t.text :preferences, limit: 500.kilobytes + 1, null: true
t.timestamps limit: 3, null: false
end
add_index :cti_caller_ids, [:caller_id]
add_index :cti_caller_ids, [:caller_id, :level]
add_index :cti_caller_ids, [:caller_id, :user_id]
add_index :cti_caller_ids, [:object, :o_id]
add_foreign_key :cti_caller_ids, :users
create_table :stats_stores do |t|
t.references :stats_store_object, null: false
@ -602,6 +661,7 @@ class CreateBase < ActiveRecord::Migration
add_index :stats_stores, [:stats_store_object_id]
add_index :stats_stores, [:created_by_id]
add_index :stats_stores, [:created_at]
add_foreign_key :stats_stores, :users, column: :created_by_id
create_table :http_logs do |t|
t.column :direction, :string, limit: 20, null: false
@ -619,6 +679,7 @@ class CreateBase < ActiveRecord::Migration
add_index :http_logs, [:facility]
add_index :http_logs, [:created_by_id]
add_index :http_logs, [:created_at]
add_foreign_key :http_logs, :users, column: :created_by_id
add_foreign_key :http_logs, :users, column: :updated_by_id
end
end

View file

@ -8,6 +8,8 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :ticket_state_types, [:name], unique: true
add_foreign_key :ticket_state_types, :users, column: :created_by_id
add_foreign_key :ticket_state_types, :users, column: :updated_by_id
create_table :ticket_states do |t|
t.references :state_type, null: false
@ -25,6 +27,9 @@ class CreateTicket < ActiveRecord::Migration
add_index :ticket_states, [:name], unique: true
add_index :ticket_states, [:default_create]
add_index :ticket_states, [:default_follow_up]
add_foreign_key :ticket_states, :ticket_state_types, column: :state_type_id
add_foreign_key :ticket_states, :users, column: :created_by_id
add_foreign_key :ticket_states, :users, column: :updated_by_id
create_table :ticket_priorities do |t|
t.column :name, :string, limit: 250, null: false
@ -37,6 +42,8 @@ class CreateTicket < ActiveRecord::Migration
end
add_index :ticket_priorities, [:name], unique: true
add_index :ticket_priorities, [:default_create]
add_foreign_key :ticket_priorities, :users, column: :created_by_id
add_foreign_key :ticket_priorities, :users, column: :updated_by_id
create_table :tickets do |t|
t.references :group, null: false
@ -102,30 +109,28 @@ class CreateTicket < ActiveRecord::Migration
add_index :tickets, [:pending_time]
add_index :tickets, [:type]
add_index :tickets, [:time_unit]
add_foreign_key :tickets, :groups
add_foreign_key :tickets, :users, column: :owner_id
add_foreign_key :tickets, :users, column: :customer_id
add_foreign_key :tickets, :ticket_priorities, column: :priority_id
add_foreign_key :tickets, :ticket_states, column: :state_id
add_foreign_key :tickets, :organizations
add_foreign_key :tickets, :users, column: :created_by_id
add_foreign_key :tickets, :users, column: :updated_by_id
create_table :ticket_flags do |t|
t.references :tickets, null: false
t.references :ticket, null: false
t.column :key, :string, limit: 50, null: false
t.column :value, :string, limit: 50, null: true
t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
end
add_index :ticket_flags, [:tickets_id, :created_by_id]
add_index :ticket_flags, [:tickets_id, :key]
add_index :ticket_flags, [:tickets_id]
add_index :ticket_flags, [:ticket_id, :created_by_id]
add_index :ticket_flags, [:ticket_id, :key]
add_index :ticket_flags, [:ticket_id]
add_index :ticket_flags, [:created_by_id]
create_table :ticket_time_accountings do |t|
t.references :ticket, null: false
t.references :ticket_article, null: true
t.column :time_unit, :decimal, precision: 6, scale: 2, null: false
t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
end
add_index :ticket_time_accountings, [:ticket_id]
add_index :ticket_time_accountings, [:ticket_article_id]
add_index :ticket_time_accountings, [:created_by_id]
add_index :ticket_time_accountings, [:time_unit]
add_foreign_key :ticket_flags, :tickets, column: :ticket_id
add_foreign_key :ticket_flags, :users, column: :created_by_id
create_table :ticket_article_types do |t|
t.column :name, :string, limit: 250, null: false
@ -137,6 +142,8 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :ticket_article_types, [:name], unique: true
add_foreign_key :ticket_article_types, :users, column: :created_by_id
add_foreign_key :ticket_article_types, :users, column: :updated_by_id
create_table :ticket_article_senders do |t|
t.column :name, :string, limit: 250, null: false
@ -146,6 +153,8 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :ticket_article_senders, [:name], unique: true
add_foreign_key :ticket_article_senders, :users, column: :created_by_id
add_foreign_key :ticket_article_senders, :users, column: :updated_by_id
create_table :ticket_articles do |t|
t.references :ticket, null: false
@ -177,18 +186,41 @@ class CreateTicket < ActiveRecord::Migration
add_index :ticket_articles, [:internal]
add_index :ticket_articles, [:type_id]
add_index :ticket_articles, [:sender_id]
add_foreign_key :ticket_articles, :tickets
add_foreign_key :ticket_articles, :ticket_article_types, column: :type_id
add_foreign_key :ticket_articles, :ticket_article_senders, column: :sender_id
add_foreign_key :ticket_articles, :users, column: :created_by_id
add_foreign_key :ticket_articles, :users, column: :updated_by_id
add_foreign_key :ticket_articles, :users, column: :origin_by_id
create_table :ticket_article_flags do |t|
t.references :ticket_articles, null: false
t.references :ticket_article, null: false
t.column :key, :string, limit: 50, null: false
t.column :value, :string, limit: 50, null: true
t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
end
add_index :ticket_article_flags, [:ticket_articles_id, :created_by_id], name: 'index_ticket_article_flags_on_articles_id_and_created_by_id'
add_index :ticket_article_flags, [:ticket_articles_id, :key]
add_index :ticket_article_flags, [:ticket_articles_id]
add_index :ticket_article_flags, [:ticket_article_id, :created_by_id], name: 'index_ticket_article_flags_on_articles_id_and_created_by_id'
add_index :ticket_article_flags, [:ticket_article_id, :key]
add_index :ticket_article_flags, [:ticket_article_id]
add_index :ticket_article_flags, [:created_by_id]
add_foreign_key :ticket_article_flags, :ticket_articles, column: :ticket_article_id
add_foreign_key :ticket_article_flags, :users, column: :created_by_id
create_table :ticket_time_accountings do |t|
t.references :ticket, null: false
t.references :ticket_article, null: true
t.column :time_unit, :decimal, precision: 6, scale: 2, null: false
t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
end
add_index :ticket_time_accountings, [:ticket_id]
add_index :ticket_time_accountings, [:ticket_article_id]
add_index :ticket_time_accountings, [:created_by_id]
add_index :ticket_time_accountings, [:time_unit]
add_foreign_key :ticket_time_accountings, :tickets
add_foreign_key :ticket_time_accountings, :ticket_articles
add_foreign_key :ticket_time_accountings, :users, column: :created_by_id
create_table :ticket_counters do |t|
t.column :content, :string, limit: 100, null: false
@ -211,27 +243,35 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :overviews, [:name]
add_foreign_key :overviews, :users, column: :created_by_id
add_foreign_key :overviews, :users, column: :updated_by_id
create_table :overviews_roles, id: false do |t|
t.integer :overview_id
t.integer :role_id
t.references :overview
t.references :role
end
add_index :overviews_roles, [:overview_id]
add_index :overviews_roles, [:role_id]
add_foreign_key :overviews_roles, :overviews
add_foreign_key :overviews_roles, :roles
create_table :overviews_users, id: false do |t|
t.integer :overview_id
t.integer :user_id
t.references :overview
t.references :user
end
add_index :overviews_users, [:overview_id]
add_index :overviews_users, [:user_id]
add_foreign_key :overviews_users, :overviews
add_foreign_key :overviews_users, :users
create_table :overviews_groups, id: false do |t|
t.integer :overview_id
t.integer :group_id
t.references :overview
t.references :group
end
add_index :overviews_groups, [:overview_id]
add_index :overviews_groups, [:group_id]
add_foreign_key :overviews_groups, :overviews
add_foreign_key :overviews_groups, :groups
create_table :triggers do |t|
t.column :name, :string, limit: 250, null: false
@ -245,6 +285,8 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :triggers, [:name], unique: true
add_foreign_key :triggers, :users, column: :created_by_id
add_foreign_key :triggers, :users, column: :updated_by_id
create_table :jobs do |t|
t.column :name, :string, limit: 250, null: false
@ -265,6 +307,8 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :jobs, [:name], unique: true
add_foreign_key :jobs, :users, column: :created_by_id
add_foreign_key :jobs, :users, column: :updated_by_id
create_table :notifications do |t|
t.column :subject, :string, limit: 250, null: false
@ -281,7 +325,7 @@ class CreateTicket < ActiveRecord::Migration
t.column :active, :boolean, null: false, default: true
t.timestamps limit: 3, null: false
end
add_index :link_types, [:name], unique: true
add_index :link_types, [:name], unique: true
create_table :link_objects do |t|
t.column :name, :string, limit: 250, null: false
@ -300,6 +344,7 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :links, [:link_object_source_id, :link_object_source_value, :link_object_target_id, :link_object_target_value, :link_type_id], unique: true, name: 'links_uniq_total'
add_foreign_key :links, :link_types
create_table :postmaster_filters do |t|
t.column :name, :string, limit: 250, null: false
@ -313,6 +358,8 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :postmaster_filters, [:channel]
add_foreign_key :postmaster_filters, :users, column: :created_by_id
add_foreign_key :postmaster_filters, :users, column: :updated_by_id
create_table :text_modules do |t|
t.references :user, null: true
@ -328,13 +375,18 @@ class CreateTicket < ActiveRecord::Migration
end
add_index :text_modules, [:user_id]
add_index :text_modules, [:name]
add_foreign_key :text_modules, :users
add_foreign_key :text_modules, :users, column: :created_by_id
add_foreign_key :text_modules, :users, column: :updated_by_id
create_table :text_modules_groups, id: false do |t|
t.integer :text_module_id
t.integer :group_id
t.references :text_module
t.references :group
end
add_index :text_modules_groups, [:text_module_id]
add_index :text_modules_groups, [:group_id]
add_foreign_key :text_modules_groups, :text_modules
add_foreign_key :text_modules_groups, :groups
create_table :templates do |t|
t.references :user, null: true
@ -346,13 +398,18 @@ class CreateTicket < ActiveRecord::Migration
end
add_index :templates, [:user_id]
add_index :templates, [:name]
add_foreign_key :templates, :users
add_foreign_key :templates, :users, column: :created_by_id
add_foreign_key :templates, :users, column: :updated_by_id
create_table :templates_groups, id: false do |t|
t.integer :template_id
t.integer :group_id
t.references :template
t.references :group
end
add_index :templates_groups, [:template_id]
add_index :templates_groups, [:group_id]
add_foreign_key :templates_groups, :templates
add_foreign_key :templates_groups, :groups
create_table :channels do |t|
t.references :group, null: true
@ -369,10 +426,13 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :channels, [:area]
add_foreign_key :channels, :groups
add_foreign_key :channels, :users, column: :created_by_id
add_foreign_key :channels, :users, column: :updated_by_id
create_table :slas do |t|
t.references :calendar, null: false
t.column :name, :string, limit: 150, null: true
t.column :calendar_id, :integer, null: false
t.column :first_response_time, :integer, null: true
t.column :update_time, :integer, null: true
t.column :solution_time, :integer, null: true
@ -382,6 +442,8 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :slas, [:name], unique: true
add_foreign_key :slas, :users, column: :created_by_id
add_foreign_key :slas, :users, column: :updated_by_id
create_table :macros do |t|
t.string :name, limit: 250, null: true
@ -393,6 +455,8 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :macros, [:name], unique: true
add_foreign_key :macros, :users, column: :created_by_id
add_foreign_key :macros, :users, column: :updated_by_id
create_table :chats do |t|
t.string :name, limit: 250, null: true
@ -406,6 +470,8 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :chats, [:name], unique: true
add_foreign_key :chats, :users, column: :created_by_id
add_foreign_key :chats, :users, column: :updated_by_id
create_table :chat_topics do |t|
t.integer :chat_id, null: false
@ -416,13 +482,15 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :chat_topics, [:name], unique: true
add_foreign_key :chat_topics, :users, column: :created_by_id
add_foreign_key :chat_topics, :users, column: :updated_by_id
create_table :chat_sessions do |t|
t.integer :chat_id, null: false
t.references :chat, null: false
t.string :session_id, null: false
t.string :name, limit: 250, null: true
t.string :state, limit: 50, null: false, default: 'waiting' # running, closed
t.integer :user_id, null: true
t.references :user, null: true
t.text :preferences, limit: 100.kilobytes + 1, null: true
t.integer :updated_by_id, null: true
t.integer :created_by_id, null: true
@ -432,14 +500,20 @@ class CreateTicket < ActiveRecord::Migration
add_index :chat_sessions, [:state]
add_index :chat_sessions, [:user_id]
add_index :chat_sessions, [:chat_id]
add_foreign_key :chat_sessions, :chats
add_foreign_key :chat_sessions, :users
add_foreign_key :chat_sessions, :users, column: :created_by_id
add_foreign_key :chat_sessions, :users, column: :updated_by_id
create_table :chat_messages do |t|
t.integer :chat_session_id, null: false
t.references :chat_session, null: false
t.text :content, limit: 20.megabytes + 1, null: false
t.integer :created_by_id, null: true
t.timestamps limit: 3, null: false
end
add_index :chat_messages, [:chat_session_id]
add_foreign_key :chat_messages, :chat_sessions
add_foreign_key :chat_messages, :users, column: :created_by_id
create_table :chat_agents do |t|
t.boolean :active, null: false, default: true
@ -451,6 +525,8 @@ class CreateTicket < ActiveRecord::Migration
add_index :chat_agents, [:active]
add_index :chat_agents, [:updated_by_id], unique: true
add_index :chat_agents, [:created_by_id], unique: true
add_foreign_key :chat_agents, :users, column: :created_by_id
add_foreign_key :chat_agents, :users, column: :updated_by_id
create_table :report_profiles do |t|
t.column :name, :string, limit: 150, null: true
@ -461,14 +537,17 @@ class CreateTicket < ActiveRecord::Migration
t.timestamps limit: 3, null: false
end
add_index :report_profiles, [:name], unique: true
add_foreign_key :report_profiles, :users, column: :created_by_id
add_foreign_key :report_profiles, :users, column: :updated_by_id
create_table :karma_users do |t|
t.integer :user_id, null: false
t.references :user, null: false
t.integer :score, null: false
t.string :level, limit: 200, null: false
t.timestamps limit: 3, null: false
end
add_index :karma_users, [:user_id], unique: true
add_foreign_key :karma_users, :users
create_table :karma_activities do |t|
t.string :name, limit: 200, null: false
@ -482,7 +561,7 @@ class CreateTicket < ActiveRecord::Migration
create_table :karma_activity_logs do |t|
t.integer :o_id, null: false
t.integer :object_lookup_id, null: false
t.integer :user_id, null: false
t.references :user, null: false
t.integer :activity_id, null: false
t.integer :score, null: false
t.integer :score_total, null: false
@ -491,7 +570,8 @@ class CreateTicket < ActiveRecord::Migration
add_index :karma_activity_logs, [:user_id]
add_index :karma_activity_logs, [:created_at]
add_index :karma_activity_logs, [:o_id, :object_lookup_id]
add_foreign_key :karma_activity_logs, :users
add_foreign_key :karma_activity_logs, :karma_activities, column: :activity_id
end
def self.down

View file

@ -0,0 +1,227 @@
class ForeignKeys < ActiveRecord::Migration
def change
# return if it's a new setup
return if !Setting.find_by(name: 'system_init_done')
# remove wrong plural of ID columns
ActiveRecord::Migration.rename_column :ticket_flags, :tickets_id, :ticket_id
ActiveRecord::Migration.rename_column :ticket_article_flags, :ticket_articles_id, :ticket_article_id
# add missing foreign keys
foreign_keys = [
# Base
[:users, :organizations],
[:users, :users, column: :created_by_id],
[:users, :users, column: :updated_by_id],
[:signatures, :users, column: :created_by_id],
[:signatures, :users, column: :updated_by_id],
[:email_addresses, :users, column: :created_by_id],
[:email_addresses, :users, column: :updated_by_id],
[:groups, :signatures],
[:groups, :email_addresses],
[:groups, :users, column: :created_by_id],
[:groups, :users, column: :updated_by_id],
[:roles, :users, column: :created_by_id],
[:roles, :users, column: :updated_by_id],
[:organizations, :users, column: :created_by_id],
[:organizations, :users, column: :updated_by_id],
[:roles_users, :users],
[:roles_users, :roles],
[:groups_users, :users],
[:groups_users, :groups],
[:organizations_users, :users],
[:organizations_users, :organizations],
[:authorizations, :users],
[:translations, :users, column: :created_by_id],
[:translations, :users, column: :updated_by_id],
[:tokens, :users],
[:packages, :users, column: :created_by_id],
[:packages, :users, column: :updated_by_id],
[:taskbars, :users],
[:tags, :tag_items],
[:tags, :tag_objects],
[:tags, :users, column: :created_by_id],
[:recent_views, :object_lookups, column: :recent_view_object_id],
[:recent_views, :users, column: :created_by_id],
[:activity_streams, :type_lookups, column: :activity_stream_type_id],
[:activity_streams, :object_lookups, column: :activity_stream_object_id],
[:activity_streams, :permissions],
[:activity_streams, :groups],
[:activity_streams, :users, column: :created_by_id],
[:histories, :history_types],
[:histories, :history_objects],
[:histories, :history_attributes],
[:histories, :users, column: :created_by_id],
[:stores, :store_objects],
[:stores, :store_files],
[:stores, :users, column: :created_by_id],
[:avatars, :users, column: :created_by_id],
[:avatars, :users, column: :updated_by_id],
[:online_notifications, :users, column: :created_by_id],
[:online_notifications, :users, column: :updated_by_id],
[:schedulers, :users, column: :created_by_id],
[:schedulers, :users, column: :updated_by_id],
[:calendars, :users, column: :created_by_id],
[:calendars, :users, column: :updated_by_id],
[:user_devices, :users],
[:object_manager_attributes, :object_lookups],
[:object_manager_attributes, :users, column: :created_by_id],
[:object_manager_attributes, :users, column: :updated_by_id],
[:cti_caller_ids, :users],
[:stats_stores, :users, column: :created_by_id],
[:http_logs, :users, column: :created_by_id],
[:http_logs, :users, column: :updated_by_id],
# Ticket
[:ticket_state_types, :users, column: :created_by_id],
[:ticket_state_types, :users, column: :updated_by_id],
[:ticket_states, :ticket_state_types, column: :state_type_id],
[:ticket_states, :users, column: :created_by_id],
[:ticket_states, :users, column: :updated_by_id],
[:ticket_priorities, :users, column: :created_by_id],
[:ticket_priorities, :users, column: :updated_by_id],
[:tickets, :groups],
[:tickets, :users, column: :owner_id],
[:tickets, :users, column: :customer_id],
[:tickets, :ticket_priorities, column: :priority_id],
[:tickets, :ticket_states, column: :state_id],
[:tickets, :organizations],
[:tickets, :users, column: :created_by_id],
[:tickets, :users, column: :updated_by_id],
[:ticket_flags, :tickets, column: :ticket_id],
[:ticket_flags, :users, column: :created_by_id],
[:ticket_article_types, :users, column: :created_by_id],
[:ticket_article_types, :users, column: :updated_by_id],
[:ticket_article_senders, :users, column: :created_by_id],
[:ticket_article_senders, :users, column: :updated_by_id],
[:ticket_articles, :tickets],
[:ticket_articles, :ticket_article_types, column: :type_id],
[:ticket_articles, :ticket_article_senders, column: :sender_id],
[:ticket_articles, :users, column: :created_by_id],
[:ticket_articles, :users, column: :updated_by_id],
[:ticket_articles, :users, column: :origin_by_id],
[:ticket_article_flags, :ticket_articles, column: :ticket_article_id],
[:ticket_article_flags, :users, column: :created_by_id],
[:ticket_time_accountings, :tickets],
[:ticket_time_accountings, :ticket_articles],
[:ticket_time_accountings, :users, column: :created_by_id],
[:overviews, :users, column: :created_by_id],
[:overviews, :users, column: :updated_by_id],
[:overviews_roles, :overviews],
[:overviews_roles, :roles],
[:overviews_users, :overviews],
[:overviews_users, :users],
[:overviews_groups, :overviews],
[:overviews_groups, :groups],
[:triggers, :users, column: :created_by_id],
[:triggers, :users, column: :updated_by_id],
[:jobs, :users, column: :created_by_id],
[:jobs, :users, column: :updated_by_id],
[:links, :link_types],
[:postmaster_filters, :users, column: :created_by_id],
[:postmaster_filters, :users, column: :updated_by_id],
[:text_modules, :users],
[:text_modules, :users, column: :created_by_id],
[:text_modules, :users, column: :updated_by_id],
[:text_modules_groups, :text_modules],
[:text_modules_groups, :groups],
[:templates, :users],
[:templates, :users, column: :created_by_id],
[:templates, :users, column: :updated_by_id],
[:templates_groups, :templates],
[:templates_groups, :groups],
[:channels, :groups],
[:channels, :users, column: :created_by_id],
[:channels, :users, column: :updated_by_id],
[:slas, :users, column: :created_by_id],
[:slas, :users, column: :updated_by_id],
[:macros, :users, column: :created_by_id],
[:macros, :users, column: :updated_by_id],
[:chats, :users, column: :created_by_id],
[:chats, :users, column: :updated_by_id],
[:chat_topics, :users, column: :created_by_id],
[:chat_topics, :users, column: :updated_by_id],
[:chat_sessions, :chats],
[:chat_sessions, :users],
[:chat_sessions, :users, column: :created_by_id],
[:chat_sessions, :users, column: :updated_by_id],
[:chat_messages, :chat_sessions],
[:chat_messages, :users, column: :created_by_id],
[:chat_agents, :users, column: :created_by_id],
[:chat_agents, :users, column: :updated_by_id],
[:report_profiles, :users, column: :created_by_id],
[:report_profiles, :users, column: :updated_by_id],
[:karma_users, :users],
[:karma_activity_logs, :users],
[:karma_activity_logs, :karma_activities, column: :activity_id],
]
foreign_keys.each do |foreign_key|
begin
ActiveRecord::Migration.add_foreign_key(*foreign_key)
rescue => e
Rails.logger.error "Inconsistent data status detected while adding foreign key '#{foreign_key.inspect}': #{e.message}"
end
end
end
end

8
spec/support/cache.rb Normal file
View file

@ -0,0 +1,8 @@
RSpec.configure do |config|
config.before(:all) do
# clear the cache otherwise it won't
# be able to recognize the rollbacks
# done by RSpec
Cache.clear
end
end

View file

@ -132,9 +132,9 @@ class AssetsTest < ActiveSupport::TestCase
assert( diff(attributes, assets[:User][user3.id]), 'check assets' )
travel_back
user1.destroy
user2.destroy
user3.destroy
user2.destroy
user1.destroy
org1.destroy
org2.destroy
@ -270,9 +270,9 @@ class AssetsTest < ActiveSupport::TestCase
assert( diff(attributes, assets[:User][user_new_2.id]), 'check assets' )
travel_back
user1.destroy
user2.destroy
user3.destroy
user2.destroy
user1.destroy
org.destroy
org_new.destroy

View file

@ -210,10 +210,12 @@ Mob: +49 333 1112222",
assert_equal(2, caller_ids[0].user_id)
assert_nil(caller_ids[0].comment)
user_id = User.find_by(login: 'ticket-caller_id-customer1@example.com').id
Cti::CallerId.maybe_add(
caller_id: '4912345678901',
level: 'maybe',
user_id: 3,
user_id: user_id,
object: 'Ticket',
o_id: 2,
)
@ -221,7 +223,7 @@ Mob: +49 333 1112222",
caller_ids = Cti::CallerId.lookup('4912345678901')
assert_equal(2, caller_ids.length)
assert_equal('maybe', caller_ids[0].level)
assert_equal(3, caller_ids[0].user_id)
assert_equal(user_id, caller_ids[0].user_id)
assert_nil(caller_ids[0].comment)
assert_equal('maybe', caller_ids[1].level)
assert_equal(2, caller_ids[1].user_id)
@ -230,7 +232,7 @@ Mob: +49 333 1112222",
Cti::CallerId.maybe_add(
caller_id: '4912345678901',
level: 'known',
user_id: 3,
user_id: user_id,
object: 'User',
o_id: 2,
)
@ -238,7 +240,7 @@ Mob: +49 333 1112222",
caller_ids = Cti::CallerId.lookup('4912345678901')
assert_equal(1, caller_ids.length)
assert_equal('known', caller_ids[0].level)
assert_equal(3, caller_ids[0].user_id)
assert_equal(user_id, caller_ids[0].user_id)
assert_nil(caller_ids[0].comment)
end

View file

@ -40,7 +40,7 @@ class EmailAddressTest < ActiveSupport::TestCase
email_address1.destroy
group1 = Group.find(group1.id)
assert(group1.email_address_id)
assert_nil(group1.email_address_id, 'References to groups are deleted')
end
test 'channel tests' do

View file

@ -550,7 +550,15 @@ class UserTest < ActiveSupport::TestCase
end
test 'min admin permission check' do
User.with_permissions('admin').each(&:destroy)
# workaround:
# - We need to get rid of all admin users but can't delete them
# because we have foreign keys pointing at them since the tests are not isolated yet :(
# - We can't just remove the roles since then our check would take place
# So we need to merge them with the User Nr 1 and destroy them afterwards
User.with_permissions('admin').each do |user|
Models.merge('User', 1, user.id)
user.destroy
end
# store current admin count
admin_count_inital = User.with_permissions('admin').count