1: <?php namespace Laravel\Database;
2:
3: abstract class Grammar {
4:
5: /**
6: * The keyword identifier for the database system.
7: *
8: * @var string
9: */
10: protected $wrapper = '"%s"';
11:
12: /**
13: * The database connection instance for the grammar.
14: *
15: * @var Connection
16: */
17: protected $connection;
18:
19: /**
20: * Create a new database grammar instance.
21: *
22: * @param Connection $connection
23: * @return void
24: */
25: public function __construct(Connection $connection)
26: {
27: $this->connection = $connection;
28: }
29:
30: /**
31: * Wrap a table in keyword identifiers.
32: *
33: * @param string $table
34: * @return string
35: */
36: public function wrap_table($table)
37: {
38: // Expressions should be injected into the query as raw strings
39: // so we do not want to wrap them in any way. We will just return
40: // the string value from the expression to be included.
41: if ($table instanceof Expression)
42: {
43: return $this->wrap($table);
44: }
45:
46: $prefix = '';
47:
48: // Tables may be prefixed with a string. This allows developers to
49: // prefix tables by application on the same database which may be
50: // required in some brown-field situations.
51: if (isset($this->connection->config['prefix']))
52: {
53: $prefix = $this->connection->config['prefix'];
54: }
55:
56: return $this->wrap($prefix.$table);
57: }
58:
59: /**
60: * Wrap a value in keyword identifiers.
61: *
62: * @param string $value
63: * @return string
64: */
65: public function wrap($value)
66: {
67: // Expressions should be injected into the query as raw strings
68: // so we do not want to wrap them in any way. We will just return
69: // the string value from the expression to be included.
70: if ($value instanceof Expression)
71: {
72: return $value->get();
73: }
74:
75: // If the value being wrapped contains a column alias, we need to
76: // wrap it a little differently as each segment must be wrapped
77: // and not the entire string.
78: if (strpos(strtolower($value), ' as ') !== false)
79: {
80: $segments = explode(' ', $value);
81:
82: return sprintf(
83: '%s AS %s',
84: $this->wrap($segments[0]),
85: $this->wrap($segments[2])
86: );
87: }
88:
89: // Since columns may be prefixed with their corresponding table
90: // name so as to not make them ambiguous, we will need to wrap
91: // the table and the column in keyword identifiers.
92: $segments = explode('.', $value);
93:
94: foreach ($segments as $key => $value)
95: {
96: if ($key == 0 and count($segments) > 1)
97: {
98: $wrapped[] = $this->wrap_table($value);
99: }
100: else
101: {
102: $wrapped[] = $this->wrap_value($value);
103: }
104: }
105:
106: return implode('.', $wrapped);
107: }
108:
109: /**
110: * Wrap a single string value in keyword identifiers.
111: *
112: * @param string $value
113: * @return string
114: */
115: protected function wrap_value($value)
116: {
117: return ($value !== '*') ? sprintf($this->wrapper, $value) : $value;
118: }
119:
120: /**
121: * Create query parameters from an array of values.
122: *
123: * <code>
124: * Returns "?, ?, ?", which may be used as PDO place-holders
125: * $parameters = $grammar->parameterize(array(1, 2, 3));
126: *
127: * // Returns "?, "Taylor"" since an expression is used
128: * $parameters = $grammar->parameterize(array(1, DB::raw('Taylor')));
129: * </code>
130: *
131: * @param array $values
132: * @return string
133: */
134: final public function parameterize($values)
135: {
136: return implode(', ', array_map(array($this, 'parameter'), $values));
137: }
138:
139: /**
140: * Get the appropriate query parameter string for a value.
141: *
142: * <code>
143: * // Returns a "?" PDO place-holder
144: * $value = $grammar->parameter('Taylor Otwell');
145: *
146: * // Returns "Taylor Otwell" as the raw value of the expression
147: * $value = $grammar->parameter(DB::raw('Taylor Otwell'));
148: * </code>
149: *
150: * @param mixed $value
151: * @return string
152: */
153: final public function parameter($value)
154: {
155: return ($value instanceof Expression) ? $value->get() : '?';
156: }
157:
158: /**
159: * Create a comma-delimited list of wrapped column names.
160: *
161: * <code>
162: * // Returns ""Taylor", "Otwell"" when the identifier is quotes
163: * $columns = $grammar->columnize(array('Taylor', 'Otwell'));
164: * </code>
165: *
166: * @param array $columns
167: * @return string
168: */
169: final public function columnize($columns)
170: {
171: return implode(', ', array_map(array($this, 'wrap'), $columns));
172: }
173:
174: }