Class: Arxutils_Sqlite3::HierOp

Inherits:
Object
  • Object
show all
Defined in:
lib/arxutils_sqlite3/hier.rb

Overview

階層処理

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(field_name, hier_symbol, _hier_name, base_klass, hier_klass, current_klass, invalid_klass) ⇒ HierOp

初期化



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/arxutils_sqlite3/hier.rb', line 24

def initialize(field_name, hier_symbol, _hier_name, base_klass, hier_klass, current_klass, invalid_klass)
  # 階層処理を付加したいフィールド名
  @field_name = field_name
  # '/'が区切り文字の文字列で階層処理を実現するクラスの階層構造を表す文字列を持つメソッド/アトリビュートを表すシンボ
  @hier_symbol = hier_symbol
  # '/'が区切り文字の文字列で階層処理を実現するクラスのクラス名(DB中のテーブルに対応するActiveRecordの子クラス)
  @base_klass = base_klass
  # '/'が区切り文字の文字列で階層処理を実現するクラスのカレントに対応するクラス名(DB中のテーブルに対応するActiveRecordの子クラス)
  @current_klass = current_klass
  # '/'が区切り文字の文字列で階層処理を実現するクラスのインバリッドに対応するクラス名(DB中のテーブルに対応するActiveRecordの子クラス)
  @invalid_klass = invalid_klass
  # IDの親子関係で階層処理を実現するクラス名(DB中のテーブルに対応するActiveRecordの子クラス)
  #  print_id(integer), child_id(integer), level(integer)
  @hier_klass = hier_klass
end

Instance Attribute Details

#base_klassObject (readonly)

‘/’が区切り文字の文字列で階層処理を実現するクラスのクラス名(DB中のテーブルに対応するActiveRecordの子クラス) シンボルhier_symbolで指定できるメソッド/アトリビュート(string)を持つ。 nameというメソッド/アトリビュート(string)を持つ。“‘/’を区切り文字として持つ階層を表す文字列 registerメソッドを呼び出す時は、hier_symbolのみを指定してcreate出来なければならない(そうでなければSQLの制約違反発生)



14
15
16
# File 'lib/arxutils_sqlite3/hier.rb', line 14

def base_klass
  @base_klass
end

#current_klassObject (readonly)

‘/’が区切り文字の文字列で階層処理を実現するクラスのカレントに対応するクラス名(DB中のテーブルに対応するActiveRecordの子クラス)



19
20
21
# File 'lib/arxutils_sqlite3/hier.rb', line 19

def current_klass
  @current_klass
end

#field_nameObject (readonly)

階層処理を付加したいフィールド名(未使用か?)



7
8
9
# File 'lib/arxutils_sqlite3/hier.rb', line 7

def field_name
  @field_name
end

#hier_klassObject (readonly)

IDの親子関係で階層処理を実現するクラス名(DB中のテーブルに対応するActiveRecordの子クラス) parent_id(integer) , child_id(integer) , leve(integer)というメソッド/アトリビュートを持つ



17
18
19
# File 'lib/arxutils_sqlite3/hier.rb', line 17

def hier_klass
  @hier_klass
end

#hier_symbolObject (readonly)

‘/’が区切り文字の文字列で階層処理を実現するクラスの階層構造を表す文字列を持つメソッド/アトリビュートを表すシンボル



9
10
11
# File 'lib/arxutils_sqlite3/hier.rb', line 9

def hier_symbol
  @hier_symbol
end

#invalid_klassObject (readonly)

‘/’が区切り文字の文字列で階層処理を実現するクラスのインバリッドに対応するクラス名(DB中のテーブルに対応するActiveRecordの子クラス)



21
22
23
# File 'lib/arxutils_sqlite3/hier.rb', line 21

def invalid_klass
  @invalid_klass
end

Instance Method Details

#delete(hier) ⇒ Object

指定した階層(階層を/で区切って表現)のアイテムをbase_klassから削除



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/arxutils_sqlite3/hier.rb', line 41

def delete(hier)
  # 子として探す
  id = nil
  base = @base_klass.find_by({ @hier_symbol => hier })
  if base
    delete_at(base.id)
    # @base_klass.delete_at(base.id)
    @base_klass.delete(base.id)
  end
  id
end

#delete_by_id(id) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/arxutils_sqlite3/hier.rb', line 53

def delete_by_id(id)
  # base = @base_klass.find_by(id: id)
  base = @base_klass.find(id)
  delete_at(id)
  @base_klass.delete_at(base.id)
  @base_klass.delete_at(base.id)
end

#move(src_hier, dest_parent_hier) ⇒ Object

文字列で指定した階層を移動



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/arxutils_sqlite3/hier.rb', line 62

def move(src_hier, dest_parent_hier)
  # dest_parent_hierがsrc_hierの子であれば(=src_hierがdest_parent_hierの先頭からの部分文字列である)何もせずエラーを返す
  escaped = Regexp.escape(src_hier)
  src_re = Regexp.new(%(^#{escaped}))
  ret = (src_re =~ dest_parent_hier)
  # 自身の子への移動はエラーとする
  return false if ret

  src_row_item = @base_klass.where(name: src_hier)
  src_num = src_row_item.id
  # srcが子である(tblでは項目を一意に指定できる)tblでの項目を得る
  src_row = @hire_klass.find_by(child_id: src_num)

  dest_parent_row_item = @base_klass.find_by(name: dest_parent_hier)
  dest_parent_num = if dest_parent_row_item
      dest_parent_row_item.id
    else
      register(dest_parent_hier)
    end
  dest_parent_level = get_level_by_child(dest_parent_num)

  # srcの親をdest_parentにする
  src_row.parent_id = dest_parent_num
  src_row.save
  # destに移動後のsrcの子のレベルを調整する
  level_adjust(src_row, dest_parent_level)
  # destに移動後のsrcのhierを再設定
  set_hier(src_row_item, make_hier(dest_parent_row_item.name, get_name(src_row_item)))
  src_row_item.save
  # destに移動後のsrcの子のhierを調整する
  hier_adjust(src_row_item)

  true
end

#register(hier) ⇒ Object

文字列で指定した階層(/を区切り文字として持つ)をhier_klassに登録



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/arxutils_sqlite3/hier.rb', line 108

def register(hier)
  hier_ary = hier.split("/")
  level = get_level_by_array(hier_ary)

  # もしhier_aryがnilだけを1個持つ配列、または空文字列だけを1個もつ配列であれば、hier_nameは空文字列になる
  item_row = @current_klass.find_by({ @hier_symbol => hier })
  if item_row
    new_num = item_row.org_id
    if level.zero?
      unless @hier_klass.find_by(child_id: new_num)
        hs = { parent_id: new_num, child_id: new_num, level: level }
        @hier_klass.create(hs)
      end
    else
      register_parent(hier_ary, new_num, level) unless @hier_klass.find_by(child_id: new_num)
    end
  else
    # @base_klassがhierだけでcreateできる場合は(他にフィールドがnot_nullでないか)、ここに来てもよい。
    # そうでなければ、SQLの制約違反が発生するため、ここに来ることを避けなければならない。
    # (あらかじめここが呼ばれないようにdatabaseに登録済みにしておかなければならない。)
    new_category = @base_klass.create({ @hier_symbol => hier })
    new_num = new_category.id
    if level.zero?
      unless @hier_klass.find_by(child_id: new_num)
        hs = { parent_id: new_num, child_id: new_num, level: level }
        @hier_klass.create(hs)
      end
    else
      register_parent(hier_ary, new_num, level)
    end
  end
  new_num
end

#register_parent(hier_ary, child_num, level) ⇒ Object

配列で指定した階層を親の階層としてhier_klassに登録



98
99
100
101
102
103
104
105
# File 'lib/arxutils_sqlite3/hier.rb', line 98

def register_parent(hier_ary, child_num, level)
  hier_ary.pop
  parent_hier_ary = hier_ary
  parent_hier = parent_hier_ary.join("/")
  parent_num = register(parent_hier)
  hs = { parent_id: parent_num, child_id: child_num, level: level }
  @hier_klass.create(hs)
end