Migration_Actions::add_columns()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 4
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 2
crap 6
1
<?php defined('SYSPATH') OR die('No direct script access.');
2
3
class Migration_Actions
4
{
5
	public $up = array();
6
	public $down = array();
7
	private $driver = NULL;
8
9
	static private $patterns = array(
10
		'add_columns'    => '/^add_(.+)_to_(.+)$/',
11
		'remove_columns' => '/^remove_(.+)_from_(.+)$/',
12
		'create_table'   => '/^create_table_(.+)$/',
13
		'drop_table'     => '/^drop_table_(.+)$/',
14
		'rename_table'   => '/^rename_table_(.+)_to_(.+)$/',
15
		'rename_column'  => '/^rename_(.+)_in_(.+)$/',
16
		'change_column'  => '/^change_(.+)_in_(.+)$/',
17
	);
18
19
	public function __construct(Migration_Driver $driver)
20
	{
21
		$this->driver = $driver;
22
	}
23
24
	public function parse($string)
25
	{
26
		foreach (explode('_also_', $string) as $part)
27 7
		{
28
			foreach (self::$patterns as $method => $pattern)
29 7
			{
30 7
				if (preg_match($pattern, $part, $matches))
31
				{
32 7
					call_user_func_array(array($this, $method), array_slice($matches, 1));
33
					break;
34 7
				}
35
			}
36 7
		}
37
38 7
		return $this;
39 7
	}
40 7
41 7
	public function template($template)
42 1
	{
43 7
		if ( ! is_file($template))
44 7
			throw new Migration_Exception("Template file :template does not exist", array($template));
45
46 7
		list($this->up, $this->down) = explode('--- DOWN ---', file_get_contents($template));
47
48
		return $this;
49
	}
50
51
	public function add_columns($columns, $table)
52
	{
53
		foreach (explode('_and_', $columns) as $column)
54
		{
55
			$this->up[] = "\$this->add_column('$table', '$column', '".self::guess_column_type($column)."');";
56
			$this->down[] = "\$this->remove_column('$table', '$column');";
57
		}
58
	}
59 2
60
	public function remove_columns($columns, $table)
61 1
	{
62
		foreach (explode('_and_', $columns) as $column)
63 1
		{
64 2
			$this->up[] = "\$this->remove_column('$table', '$column');";
65 1
66 1
			try
67
			{
68 1
				$field_params = $this->driver->column($column)->load($table);
69 1
70 1
				$this->down[] = "\$this->add_column('$table', '$column', ".self::field_params_to_string($field_params).");";
71
			}
72 1
			catch (Migration_Exception $e)
73
			{
74
				$this->down[] = "\$this->add_column('$table', '$column', 'string');";
75
			}
76 1
		}
77
	}
78
79
	public function create_table($tables)
80 1
	{
81
		foreach (explode('_and_', $tables) as $table_name)
82 1
		{
83
			$this->up[] = "\$this->create_table('{$table_name}', array( ));";
84 1
			$this->down[] = "\$this->drop_table('{$table_name}');";
85 1
		}
86
	}
87 2
88
	public function drop_table($tables)
89 2
	{
90
		foreach (explode('_and_', $tables) as $table_name)
91 2
		{
92 2
			$this->up[] = "\$this->drop_table('{$table_name}');";
93 2
94 2
			try
95
			{
96 1
				$table = $this->driver->table($table_name)->load();
97
				$fields = array();
98 1
				$options = array();
99
100 1
				foreach ($table->columns as $name => $field_params)
101
				{
102
					$fields[] = "\n\t\t\t'$name' => ".self::field_params_to_string($field_params);
103
				}
104 1
105
				foreach($table->options as $name => $option)
106
				{
107
					$options[] = "'$name' => '$option'";
108
				}
109
110
				$this->down[] = "\$this->create_table('{$table->name()}', array( ".join(',', $fields)." \n\t\t), array( ".join(',', $options)." )); ";
111
			}
112
			catch (Migration_Exception $e)
113
			{
114
				$this->down[] = "\$this->create_table('{$table_name}', array( ));";
115
			}
116
		}
117
	}
118
119
	public function rename_table($old_name, $new_name)
120 1
	{
121
		$this->up[] = "\$this->rename_table('$old_name', '$new_name');";
122 1
		$this->down[] = "\$this->rename_table('$new_name', '$old_name');";
123
	}
124 1
125 1
	public function rename_column($columns, $table)
126
	{
127
		foreach (explode('_and_', $columns) as $column)
128
		{
129
			if (preg_match('/^(.+)_to_(.+)$/', $column, $matches))
130
			{
131
				if (count($matches) === 3)
132
				{
133 1
					$old_name = $matches[1];
134
					$new_name = $matches[2];
135 1
					$this->up[] = "\$this->rename_column('$table', '$old_name', '$new_name');";
136
					$this->down[] = "\$this->rename_column('$table', '$new_name', '$old_name');";
137 1
				}
138 1
			}
139 1
		}
140 1
	}
141 1
142 1
	public function change_column($columns, $table)
143 1
	{
144 1
		foreach (explode('_and_', $columns) as $column)
145 1
		{
146 1
			$this->up[] = "\$this->change_column('$table', '$column', '".self::guess_column_type($column)."');";
147 1
148 1
			try
149
			{
150 1
				$field_params = $this->driver->column($column)->load($table);
151
152 1
				$this->down[] = "\$this->change_column('$table', '$column', ".self::field_params_to_string($field_params).");";
153
			}
154 1
			catch (Migration_Exception $e)
155
			{
156
				$this->down[] = "\$this->change_column('$table', '$column', 'string');";
157
			}
158 1
		}
159
	}
160
161
	static public function field_params_to_string($column)
162 1
	{
163
		$options = array();
164 1
165
		foreach ($column->params() as $option_name => $option)
166 1
		{
167 1
			if ($option) {
168
				if (is_array($option))
169
				{
170
					foreach ($option as & $param)
171
					{
172
						$param = "'$param'";
173
					}
174
					$option = 'array('.join(', ', $option).')';
175
				}
176
				elseif (is_bool($option))
177
				{
178
					$option = $option ? 'TRUE' : 'FALSE';
179
				}
180
				elseif (is_string($option))
181
				{
182
					$option = "'$option'";
183
				}
184
				$options[] = (is_numeric($option_name) ? '' : '"' . $option_name . '" => ') . $option;
185
			}
186
		}
187
188
		return "array( ".join(', ', $options).')';
189
	}
190
191
192
	static public function guess_column_type($column)
193
	{
194
		if (preg_match('/_id$/', $column))
195
			return 'integer';
196
197
		if (preg_match('/^(id|position)$/', $column))
198
			return 'integer';
199
200 2
		if (preg_match('/(_count|_width|_height|_x|_y)$/', $column))
201
			return 'integer';
202 2
203 2
		if (preg_match('/_at$/', $column))
204
			return 'datetime';
205 2
206 2
		if (preg_match('/^is_/', $column))
207
			return 'boolean';
208 2
209 2
		if (preg_match('/_on$/', $column))
210
			return 'date';
211 2
212 2
			if (preg_match('/^(description|text)$/', $column))
213
				return 'text';
214 2
215 2
		return 'string';
216
	}
217
}
218