1: <?php
2: /**
3: * This code is licensed under AGPLv3 license or Afterlogic Software License
4: * if commercial version of the product was purchased.
5: * For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
6: */
7:
8: namespace Aurora\System\Db;
9:
10: /**
11: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
12: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
13: * @copyright Copyright (c) 2019, Afterlogic Corp.
14: *
15: * @package Api
16: * @subpackage Db
17: */
18: class Table
19: {
20: public const CRLF = "\r\n";
21: public const TAB = "\t";
22:
23: /**
24: * @var string
25: */
26: protected $sName;
27:
28: /**
29: * @var string
30: */
31: protected $sPrefix;
32:
33: /**
34: * @var array
35: */
36: protected $aFields;
37:
38: /**
39: * @var array
40: */
41: protected $aKeys;
42:
43: /**
44: * @param string $sName
45: * @param string $sPrefix
46: * @param array $aFields
47: * @param array $aKeys = array()
48: */
49: public function __construct($sName, $sPrefix, array $aFields, $aKeys = array())
50: {
51: $this->sName = $sName;
52: $this->sPrefix = $sPrefix;
53: $this->aFields = $aFields;
54: $this->aKeys = $aKeys;
55: }
56:
57: /**
58: * @return string
59: */
60: public function Name($nWithPrefix = true)
61: {
62: return (($nWithPrefix) ? $this->sPrefix : '').$this->sName;
63: }
64:
65: /**
66: * @return array
67: */
68: public function &GetFields()
69: {
70: return $this->aFields;
71: }
72:
73: /**
74: * @return array
75: */
76: public function GetFieldNames()
77: {
78: $aField = array();
79: foreach ($this->aFields as /* @var $oField Field */ $oField) {
80: $aField[] = $oField->Name();
81: }
82: return $aField;
83: }
84:
85: /**
86: * @return array
87: */
88: public function GetIndexesFieldsNames()
89: {
90: $aKeyLines = array();
91: foreach ($this->aKeys as /* @var $oKey Key */ $oKey) {
92: if (Key::TYPE_PRIMARY_KEY !== $oKey->GetType()) {
93: $aKeyFields = $oKey->GetIndexesFields();
94: if (is_array($aKeyFields) && 0 < count($aKeyFields)) {
95: $aKeyLines[] = $aKeyFields;
96: }
97: }
98: }
99: return $aKeyLines;
100: }
101:
102: /**
103: * @param string $sName
104: * @return Field
105: */
106: public function GetFieldByName($sName)
107: {
108: $oResultField = false;
109: foreach ($this->aFields as /* @var $oField Field */ $oField) {
110: if ($sName === $oField->Name()) {
111: $oResultField = $oField;
112: break;
113: }
114: }
115: return $oResultField;
116: }
117:
118: /**
119: * @param IDbHelper $oHelper
120: * @param bool $bAddDropTable = false
121: * @return string
122: */
123: public function ToString($oHelper, $bAddDropTable = false)
124: {
125: $sResult = '';
126: if ($bAddDropTable) {
127: $sResult .= 'DROP TABLE IF EXISTS '.$oHelper->EscapeColumn($this->Name()).';'.Table::CRLF;
128: }
129:
130: $sResult .= 'CREATE TABLE '.$oHelper->EscapeColumn($this->Name())
131: .' ('.Table::CRLF.Table::TAB;
132:
133: $aFieldLines = array();
134: foreach ($this->aFields as /* @var $oField Field */ $oField) {
135: $aFieldLines[] = $oField->ToString($oHelper);
136: }
137:
138: $sResult .= implode(','.Table::CRLF.Table::TAB, $aFieldLines);
139: unset($aFieldLines);
140:
141: $aAdditionalRequests = array();
142:
143: $aKeyLines = array();
144: foreach ($this->aKeys as /* @var $oKey Key */ $oKey) {
145: if (Key::TYPE_PRIMARY_KEY === $oKey->GetType() || !$oHelper->UseSingleIndexRequest()) {
146: $sLine = $oKey->ToString($oHelper, $this->Name());
147: if (!empty($sLine)) {
148: $aKeyLines[] = $sLine;
149: }
150: } else {
151: $aAdd = $oKey->ToSingleIndexRequest($oHelper, $this->Name());
152: if (!empty($aAdd)) {
153: $aAdditionalRequests[] = $aAdd;
154: }
155: }
156: }
157:
158: if (0 < count($aKeyLines)) {
159: $sResult .= ','.Table::CRLF.Table::TAB.
160: implode(','.Table::CRLF.Table::TAB, $aKeyLines);
161: }
162:
163: unset($aKeyLines);
164:
165: return trim($sResult.Table::CRLF.') '.$oHelper->CreateTableLastLine()).
166: (0 < count($aAdditionalRequests) ? ";\n\n".implode(";\n\n", $aAdditionalRequests) : '');
167: }
168:
169: /**
170: * @param IDbHelper $oHelper
171: * @param array $aFieldsToAdd
172: * @return string
173: */
174: public function GetAlterAddFields($oHelper, $aFieldsToAdd)
175: {
176: if (0 < count($aFieldsToAdd)) {
177: $aLines = array();
178: foreach ($this->aFields as /* @var $oField Field */ $oField) {
179: if (in_array($oField->Name(), $aFieldsToAdd)) {
180: $aLines[] = 'ADD '.$oField->ToString($oHelper);
181: }
182: }
183:
184: return sprintf('ALTER TABLE %s %s', $oHelper->EscapeColumn($this->Name()), implode(', ', $aLines));
185: }
186:
187: return false;
188: }
189:
190: /**
191: * @param IDbHelper $oHelper
192: * @param array $aFieldsToDelete
193: * @return string
194: */
195: public function GetAlterDeleteFields($oHelper, $aFieldsToDelete)
196: {
197: if (0 < count($aFieldsToDelete)) {
198: $aLines = array();
199: foreach ($aFieldsToDelete as $sFieldName) {
200: $aLines[] = 'DROP '.$oHelper->EscapeColumn($sFieldName);
201: }
202:
203: return sprintf('ALTER TABLE %s %s', $oHelper->EscapeColumn($this->Name()), implode(', ', $aLines));
204: }
205:
206: return false;
207: }
208:
209: /**
210: * @param IDbHelper $oHelper
211: * @param array $aIndexesToCreate
212: * @return string
213: */
214: public function GetAlterCreateIndexes($oHelper, $aIndexesToCreate)
215: {
216: if (0 < count($aIndexesToCreate)) {
217: $sName = strtoupper('awm_'.$this->Name().'_'.implode('_', $aIndexesToCreate).'_index');
218: $aIndexesToCreate = array_map(array($oHelper, 'EscapeColumn'), $aIndexesToCreate);
219:
220: return sprintf(
221: 'CREATE INDEX %s ON %s (%s)',
222: $sName,
223: $oHelper->EscapeColumn($this->Name()),
224: implode(', ', $aIndexesToCreate)
225: );
226: }
227:
228: return false;
229: }
230:
231: /**
232: * @param IDbHelper $oHelper
233: * @param string $sIndexesName
234: * @return string
235: */
236: public function GetAlterDeleteIndexes($oHelper, $sIndexesName)
237: {
238: if (!empty($sIndexesName)) {
239: return $oHelper->DropIndexRequest($sIndexesName, $this->Name());
240: }
241:
242: return false;
243: }
244: }
245: