1: <?php
2: /*
3: * The MIT License
4: *
5: * Copyright 2017 David Schoenbauer <dschoenbauer@gmail.com>.
6: *
7: * Permission is hereby granted, free of charge, to any person obtaining a copy
8: * of this software and associated documentation files (the "Software"), to deal
9: * in the Software without restriction, including without limitation the rights
10: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11: * copies of the Software, and to permit persons to whom the Software is
12: * furnished to do so, subject to the following conditions:
13: *
14: * The above copyright notice and this permission notice shall be included in
15: * all copies or substantial portions of the Software.
16: *
17: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23: * THE SOFTWARE.
24: */
25: namespace DSchoenbauer\Sql\Command;
26:
27: use DSchoenbauer\Sql\Exception\EmptyDatasetException;
28: use DSchoenbauer\Sql\Exception\ExecutionErrorException;
29: use DSchoenbauer\Sql\Where\WhereStatementInterface;
30: use PDO;
31:
32: /**
33: * updates values in a PDO connected resource
34: * @author David Schoenbauer <dschoenbauer@gmail.com>
35: * @since v1.0.0
36: */
37: class Update implements CommandInterface
38: {
39:
40: private $table;
41: private $data = [];
42:
43: use WhereTrait;
44:
45: /**
46: * @param string $table table with which you wish to append to
47: * @param array $data a single level associative array containing keys that
48: * represent the fields and values that represent new values to be added into
49: * the table
50: * @param WhereStatementInterface $where an object that is designed to return
51: * a where statement to limit the data that is affected by the update
52: * @since v1.0.0
53: */
54: public function __construct(
55: $table,
56: array $data,
57: WhereStatementInterface $where = null
58: ) {
59:
60: $this->setTable($table)->setData($data)->setWhere($where);
61: }
62:
63: /**
64: * takes the SQL and the data provided and executes the query with the data
65: * @param PDO $pdo a connection object that defines where the connection is
66: * to be executed
67: * @return bool TRUE on success or FALSE on failure.
68: * @throws EmptyDatasetException if no data has been set no fields can be
69: * discerned and no query can be made
70: * @throws ExecutionErrorException thrown when any exception or SQL failure
71: * occurs
72: * @since v1.0.0
73: */
74: public function execute(PDO $pdo)
75: {
76: try {
77: $stmt = $pdo->prepare($this->getSql());
78: return $stmt->execute($this->getCombinedData());
79: } catch (EmptyDatasetException $exc) {
80: throw $exc;
81: } catch (\Exception $exc) {
82: throw new ExecutionErrorException($exc->getMessage());
83: }
84: }
85:
86: /**
87: * Generates a SQL statement ready to be prepared for execution with the
88: * intent of updating data
89: * @return string a string that represents an update statement ready to be
90: * prepared by PDO
91: * @throws EmptyDatasetException if no data has been set no fields can be
92: * discerned and no query can be made
93: * @since v1.0.0
94: */
95: public function getSql()
96: {
97: if (count($this->getData()) === 0) {
98: throw new EmptyDatasetException();
99: }
100:
101: $sets = array_map(function ($value) {
102: return sprintf('%1$s = :%1$s', $value);
103: }, array_keys($this->getData()));
104: $where = $this->getWhereStatement();
105: $sqlTemplate = "UPDATE %s SET %s %s";
106: return trim(sprintf(
107: $sqlTemplate,
108: $this->getTable(),
109: implode(',', $sets),
110: $where
111: ));
112: }
113:
114: /**
115: * retrieves the table with which you wish to update
116: * @return string table with which you wish to update
117: * @since v1.0.0
118: */
119: public function getTable()
120: {
121: return $this->table;
122: }
123:
124: /**
125: * defines a table with which you wish to update
126: * @param string $table a table with which you wish to update
127: * @return Update for method chaining
128: * @since v1.0.0
129: */
130: public function setTable($table)
131: {
132: $this->table = $table;
133: return $this;
134: }
135:
136: /**
137: * Returns a combination of data from Where statement and from this object
138: * @return array
139: * @since v1.0.0
140: */
141: public function getCombinedData()
142: {
143: $whereData = $this->getWhereData();
144: return array_merge($this->getData(), $whereData);
145: }
146:
147: /**
148: * retrieves the data that is used to generate the update statement. The
149: * fields of the array are used to generate the field list.
150: * @return array a single level associative array containing keys that
151: * represent the fields and values that represent new values to be updated in the table
152: * @since v1.0.0
153: */
154: public function getData()
155: {
156: return $this->data;
157: }
158:
159: /**
160: * sets the data that is used to generate the update statement. The fields
161: * of the array are used to generate the field list.
162: * @param array $data a single level associative array containing keys that
163: * represent the fields and values that represent values to be updated into the table
164: * @return Update for method chaining
165: * @since v1.0.0
166: */
167: public function setData($data)
168: {
169: $this->data = $data;
170: return $this;
171: }
172: }
173: