1: <?php
2:
3: namespace Yajra\Oci8\Eloquent;
4:
5: use Illuminate\Database\Eloquent\Builder;
6: use Illuminate\Database\Query\Builder as IlluminateQueryBuilder;
7: use Illuminate\Database\Eloquent\Model;
8: use Yajra\Oci8\Oci8Connection;
9: use Yajra\Oci8\Query\Grammars\OracleGrammar;
10: use Yajra\Oci8\Query\OracleBuilder as QueryBuilder;
11:
12: class OracleEloquent extends Model
13: {
14: /**
15: * List of binary (blob) columns
16: *
17: * @var array
18: */
19: protected $binaries = [];
20:
21: /**
22: * @var array
23: */
24: protected $wrapBinaries = [];
25:
26: /**
27: * Sequence name variable
28: *
29: * @var string
30: */
31: protected $sequence = null;
32:
33: /**
34: * Get model's sequence name
35: *
36: * @return string
37: */
38: public function getSequenceName()
39: {
40: if ($this->sequence) {
41: return $this->sequence;
42: }
43:
44: return $this->getTable() . '_' . $this->getKeyName() . '_seq';
45: }
46:
47: /**
48: * Set sequence name
49: *
50: * @param string $name
51: * @return string
52: */
53: public function setSequenceName($name)
54: {
55: return $this->sequence = $name;
56: }
57:
58: /**
59: * Update the model in the database.
60: *
61: * @param array $attributes
62: * @param array $options
63: * @return bool|int
64: */
65: public function update(array $attributes = [], array $options = [])
66: {
67: if (! $this->exists) {
68: // If dirty attributes contains binary field
69: // extract binary fields to new array
70: if ($this->wrapBinary($dirty)) {
71: return $this->newQuery()->updateLob($attributes, $this->wrapBinaries, $this->getKeyName());
72: }
73:
74: return $this->newQuery()->update($attributes);
75: }
76:
77: return $this->fill($attributes)->save();
78: }
79:
80: /**
81: * wrap binaries to each attributes
82: *
83: * @param array $attributes
84: * @return array
85: */
86: public function wrapBinary(&$attributes)
87: {
88: // If attributes contains binary field
89: // extract binary fields to new array
90: $binaries = [];
91: if ($this->checkBinary($attributes) and $this->getConnection() instanceof Oci8Connection) {
92: foreach ($attributes as $key => $value) {
93: if (in_array($key, $this->binaries)) {
94: $binaries[$key] = $value;
95: unset($attributes[$key]);
96: }
97: }
98: }
99:
100: return $this->wrapBinaries = $binaries;
101: }
102:
103: /**
104: * Check if attributes contains binary field
105: *
106: * @param array $attributes
107: * @return boolean
108: */
109: public function checkBinary(array $attributes)
110: {
111: foreach ($attributes as $key => $value) {
112: // if attribute is in binary field list
113: if (in_array($key, $this->binaries)) {
114: return true;
115: }
116: }
117:
118: return false;
119: }
120:
121: /**
122: * Get the table qualified key name.
123: *
124: * @return string
125: */
126: public function getQualifiedKeyName()
127: {
128: $pos = strpos($this->getTable(), '@');
129:
130: if ($pos === false) {
131: return $this->getTable() . '.' . $this->getKeyName();
132: } else {
133: $table = substr($this->getTable(), 0, $pos);
134: $dblink = substr($this->getTable(), $pos);
135:
136: return $table . '.' . $this->getKeyName() . $dblink;
137: }
138: }
139:
140: /**
141: * Get a new query builder instance for the connection.
142: *
143: * @return \Yajra\Oci8\Query\OracleBuilder
144: */
145: protected function newBaseQueryBuilder()
146: {
147:
148: $conn = $this->getConnection();
149: $grammar = $conn->getQueryGrammar();
150:
151: if ($grammar instanceof OracleGrammar) {
152: return new QueryBuilder($conn, $grammar, $conn->getPostProcessor());
153: }
154:
155: return new IlluminateQueryBuilder($conn, $grammar, $conn->getPostProcessor());
156: }
157:
158: /**
159: * Perform a model update operation.
160: *
161: * @param \Illuminate\Database\Eloquent\Builder $query
162: * @param array $options
163: * @return boolean
164: */
165: protected function performUpdate(Builder $query, array $options = [])
166: {
167: $dirty = $this->getDirty();
168:
169: if (count($dirty) > 0) {
170: // If the updating event returns false, we will cancel the update operation so
171: // developers can hook Validation systems into their models and cancel this
172: // operation if the model does not pass validation. Otherwise, we update.
173: if ($this->fireModelEvent('updating') === false) {
174: return false;
175: }
176:
177: // First we need to create a fresh query instance and touch the creation and
178: // update timestamp on the model which are maintained by us for developer
179: // convenience. Then we will just continue saving the model instances.
180: if ($this->timestamps && array_get($options, 'timestamps', true)) {
181: $this->updateTimestamps();
182: }
183:
184: // Once we have run the update operation, we will fire the "updated" event for
185: // this model instance. This will allow developers to hook into these after
186: // models are updated, giving them a chance to do any special processing.
187: $dirty = $this->getDirty();
188:
189: if (count($dirty) > 0) {
190: // If dirty attributes contains binary field
191: // extract binary fields to new array
192: $this->updateBinary($query, $dirty, $options);
193:
194: $this->fireModelEvent('updated', false);
195: }
196: }
197:
198: return true;
199: }
200:
201: /**
202: * @param Builder $query
203: * @param array $dirty
204: * @param array $options
205: */
206: protected function updateBinary(Builder $query, $dirty, $options = [])
207: {
208: if ($this->wrapBinary($dirty)) {
209: $this->setKeysForSaveQuery($query)->updateLob($dirty, $this->wrapBinaries, $this->getKeyName());
210: } else {
211: $this->setKeysForSaveQuery($query)->update($dirty, $options);
212: }
213: }
214:
215: /**
216: * Perform a model insert operation.
217: *
218: * @param \Illuminate\Database\Eloquent\Builder $query
219: * @param array $options
220: * @return bool
221: */
222: protected function performInsert(Builder $query, array $options = [])
223: {
224: if ($this->fireModelEvent('creating') === false) {
225: return false;
226: }
227:
228: // First we'll need to create a fresh query instance and touch the creation and
229: // update timestamps on this model, which are maintained by us for developer
230: // convenience. After, we will just continue saving these model instances.
231: if ($this->timestamps && array_get($options, 'timestamps', true)) {
232: $this->updateTimestamps();
233: }
234:
235: // If the model has an incrementing key, we can use the "insertGetId" method on
236: // the query builder, which will give us back the final inserted ID for this
237: // table from the database. Not all tables have to be incrementing though.
238: $attributes = $this->attributes;
239:
240: if ($this->incrementing) {
241: $this->insertAndSetId($query, $attributes);
242: }
243:
244: // If the table is not incrementing we'll simply insert this attributes as they
245: // are, as this attributes arrays must contain an "id" column already placed
246: // there by the developer as the manually determined key for these models.
247: else {
248: // If attributes contains binary field
249: // extract binary fields to new array
250: if ($this->wrapBinary($attributes)) {
251: $query->getQuery()->insertLob($attributes, $this->wrapBinaries, $this->getKeyName());
252: } else {
253: $query->insert($attributes);
254: }
255: }
256:
257: // We will go ahead and set the exists property to true, so that it is set when
258: // the created event is fired, just in case the developer tries to update it
259: // during the event. This will allow them to do so and run an update here.
260: $this->exists = true;
261:
262: $this->wasRecentlyCreated = true;
263:
264: $this->fireModelEvent('created', false);
265:
266: return true;
267: }
268:
269: /**
270: * Insert the given attributes and set the ID on the model.
271: *
272: * @param \Illuminate\Database\Eloquent\Builder $query
273: * @param array $attributes
274: * @return int|void
275: */
276: protected function insertAndSetId(Builder $query, $attributes)
277: {
278: if ($binaries = $this->wrapBinary($attributes)) {
279: $id = $query->getQuery()->insertLob($attributes, $binaries, $keyName = $this->getKeyName());
280: } else {
281: $id = $query->insertGetId($attributes, $keyName = $this->getKeyName());
282: }
283:
284: $this->setAttribute($keyName, $id);
285: }
286: }
287: