-
Notifications
You must be signed in to change notification settings - Fork 6
/
ActiveRecord.php
209 lines (186 loc) · 6.55 KB
/
ActiveRecord.php
1
2
3
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
75
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
107
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
<?php
namespace xj\xunsearch;
use Yii;
use yii\base\InvalidConfigException;
use yii\base\NotSupportedException;
use yii\db\BaseActiveRecord;
use yii\helpers\Inflector;
use yii\helpers\StringHelper;
/**
* Xunsearch AR
* @author xjflyttp <[email protected]>
*/
class ActiveRecord extends BaseActiveRecord {
public static function tableName() {
return StringHelper::basename(get_called_class());
}
/**
* Returns the database connection used by this AR class.
* By default, the "redis" application component is used as the database connection.
* You may override this method if you want to use a different database connection.
* @return Database
*/
public static function getDb() {
$conn = Yii::$app->get('xunsearch');
return $conn->getDatabase(static::tableName());
}
/**
* @inheritdoc
* @return \xj\xunsearch\ActiveRecord
*/
public static function find() {
return Yii::createObject(ActiveQuery::className(), [get_called_class()]);
}
/**
* Find Model By PK
* @param int|string $id
* @return Database
*/
public static function findByPk($id) {
$find = static::find();
$pk = static::primaryKey();
$pk = $pk[0];
return $find->where([$pk => $id])->one();
}
/**
* Returns the primary key name(s) for this AR class.
* This method should be overridden by child classes to define the primary key.
*
* Note that an array should be returned even when it is a single primary key.
*
* @return string[] the primary keys of this record.
*/
public static function primaryKey() {
return ['id'];
}
/**
* Returns the list of all attribute names of the model.
* This method must be overridden by child classes to define available attributes.
* @return array list of attribute names.
*/
public function attributes() {
throw new InvalidConfigException('The attributes() method of redis ActiveRecord has to be implemented by child classes.');
}
/**
* @inheritdoc
*/
public function insert($runValidation = true, $attributes = null) {
if ($runValidation && !$this->validate($attributes)) {
return false;
}
if (!$this->beforeSave(true)) {
return false;
}
$db = static::getDb();
$values = $this->getDirtyAttributes($attributes);
$doc = new XSDocument();
$doc->setFields($values);
$db = static::getDb();
$db->getIndex()->add($doc);
$changedAttributes = array_fill_keys(array_keys($values), null);
$this->setOldAttributes($values);
$this->afterSave(true, $changedAttributes);
return true;
}
public function update($runValidation = true, $attributeNames = null) {
if ($runValidation && !$this->validate($attributes)) {
return false;
}
if (!$this->beforeSave(true)) {
return false;
}
$db = static::getDb();
$values = $this->getDirtyAttributes($attributes);
$doc = new XSDocument();
$doc->setFields($values);
$db = static::getDb();
$db->getIndex()->update($doc);
$changedAttributes = array_fill_keys(array_keys($values), null);
$this->setOldAttributes($values);
$this->afterSave(true, $changedAttributes);
return true;
}
/**
* Deletes the table row corresponding to this active record.
*
* This method performs the following steps in order:
*
* 1. call [[beforeDelete()]]. If the method returns false, it will skip the
* rest of the steps;
* 2. delete the record from the database;
* 3. call [[afterDelete()]].
*
* In the above step 1 and 3, events named [[EVENT_BEFORE_DELETE]] and [[EVENT_AFTER_DELETE]]
* will be raised by the corresponding methods.
*
* @return integer|boolean the number of rows deleted, or false if the deletion is unsuccessful for some reason.
* Note that it is possible the number of rows deleted is 0, even though the deletion execution is successful.
* @throws StaleObjectException if [[optimisticLock|optimistic locking]] is enabled and the data
* being deleted is outdated.
* @throws \Exception in case delete failed.
*/
public function delete() {
$result = false;
if ($this->beforeDelete()) {
// we do not check the return value of deleteAll() because it's possible
// the record is already deleted in the database and thus the method will return 0
$condition = $this->getOldPrimaryKey(true);
$result = $this->deleteAll($condition);
if (!$result) {
throw new StaleObjectException('The object being deleted is outdated.');
}
$this->setOldAttributes(null);
$this->afterDelete();
}
return $result;
}
/**
*
* @param array $attributes attribute values (name-value pairs) to be saved into the table
* @param array $condition the conditions that will be put in the WHERE part of the UPDATE SQL.
* @throws NotSupportedException
*/
public static function updateAll($attributes, $condition = null) {
throw new NotSupportedException;
}
/**
* Deletes rows in the table using the provided conditions.
* WARNING: If you do not specify any condition, this method will delete ALL rows in the table.
*
* For example, to delete all customers whose status is 3:
*
* ~~~
* Customer::deleteAll(['status' => 3]);
* ~~~
*
* @param array $condition the conditions that will be put in the WHERE part of the DELETE SQL.
* Please refer to [[ActiveQuery::where()]] on how to specify this parameter.
* @return integer the number of rows deleted
*/
public static function deleteAll($condition = null) {
$pks = self::fetchPks($condition);
if (empty($pks)) {
return 0;
}
return static::getDb()->getIndex()->del($pks);
}
/**
*
* @param type $condition
* @return []int
*/
private static function fetchPks($condition) {
$query = static::find();
$records = $query
->where($condition)
->asArray()
->all();
$primaryKey = static::primaryKey();
$pks = [];
foreach ($records as $record) {
$pk = $record[$primaryKey[0]];
$pks[] = is_numeric($pk) ? intval($pk) : $pk;
}
return $pks;
}
}