PgsqlAdapter.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. /**
  3. * @package ActiveRecord
  4. */
  5. namespace ActiveRecord;
  6. /**
  7. * Adapter for Postgres (not completed yet)
  8. *
  9. * @package ActiveRecord
  10. */
  11. class PgsqlAdapter extends Connection
  12. {
  13. static $QUOTE_CHARACTER = '"';
  14. static $DEFAULT_PORT = 5432;
  15. public function supports_sequences()
  16. {
  17. return true;
  18. }
  19. public function get_sequence_name($table, $column_name)
  20. {
  21. return "{$table}_{$column_name}_seq";
  22. }
  23. public function next_sequence_value($sequence_name)
  24. {
  25. return "nextval('" . str_replace("'","\\'",$sequence_name) . "')";
  26. }
  27. public function limit($sql, $offset, $limit)
  28. {
  29. return $sql . ' LIMIT ' . intval($limit) . ' OFFSET ' . intval($offset);
  30. }
  31. public function query_column_info($table)
  32. {
  33. $sql = <<<SQL
  34. SELECT
  35. a.attname AS field,
  36. a.attlen,
  37. REPLACE(pg_catalog.format_type(a.atttypid, a.atttypmod), 'character varying', 'varchar') AS type,
  38. a.attnotnull AS not_nullable,
  39. (SELECT 't'
  40. FROM pg_index
  41. WHERE c.oid = pg_index.indrelid
  42. AND a.attnum = ANY (pg_index.indkey)
  43. AND pg_index.indisprimary = 't'
  44. ) IS NOT NULL AS pk,
  45. REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE((SELECT pg_attrdef.adsrc
  46. FROM pg_attrdef
  47. WHERE c.oid = pg_attrdef.adrelid
  48. AND pg_attrdef.adnum=a.attnum
  49. ),'::[a-z_ ]+',''),'''$',''),'^''','') AS default
  50. FROM pg_attribute a, pg_class c, pg_type t
  51. WHERE c.relname = ?
  52. AND a.attnum > 0
  53. AND a.attrelid = c.oid
  54. AND a.atttypid = t.oid
  55. ORDER BY a.attnum
  56. SQL;
  57. $values = array($table);
  58. return $this->query($sql,$values);
  59. }
  60. public function query_for_tables()
  61. {
  62. return $this->query("SELECT tablename FROM pg_tables WHERE schemaname NOT IN('information_schema','pg_catalog')");
  63. }
  64. public function create_column(&$column)
  65. {
  66. $c = new Column();
  67. $c->inflected_name = Inflector::instance()->variablize($column['field']);
  68. $c->name = $column['field'];
  69. $c->nullable = ($column['not_nullable'] ? false : true);
  70. $c->pk = ($column['pk'] ? true : false);
  71. $c->auto_increment = false;
  72. if (substr($column['type'],0,9) == 'timestamp')
  73. {
  74. $c->raw_type = 'datetime';
  75. $c->length = 19;
  76. }
  77. elseif ($column['type'] == 'date')
  78. {
  79. $c->raw_type = 'date';
  80. $c->length = 10;
  81. }
  82. else
  83. {
  84. preg_match('/^([A-Za-z0-9_]+)(\(([0-9]+(,[0-9]+)?)\))?/',$column['type'],$matches);
  85. $c->raw_type = (count($matches) > 0 ? $matches[1] : $column['type']);
  86. $c->length = count($matches) >= 4 ? intval($matches[3]) : intval($column['attlen']);
  87. if ($c->length < 0)
  88. $c->length = null;
  89. }
  90. $c->map_raw_type();
  91. if ($column['default'])
  92. {
  93. preg_match("/^nextval\('(.*)'\)$/",$column['default'],$matches);
  94. if (count($matches) == 2)
  95. $c->sequence = $matches[1];
  96. else
  97. $c->default = $c->cast($column['default'],$this);
  98. }
  99. return $c;
  100. }
  101. public function set_encoding($charset)
  102. {
  103. $this->query("SET NAMES '$charset'");
  104. }
  105. public function native_database_types()
  106. {
  107. return array(
  108. 'primary_key' => 'serial primary key',
  109. 'string' => array('name' => 'character varying', 'length' => 255),
  110. 'text' => array('name' => 'text'),
  111. 'integer' => array('name' => 'integer'),
  112. 'float' => array('name' => 'float'),
  113. 'datetime' => array('name' => 'datetime'),
  114. 'timestamp' => array('name' => 'timestamp'),
  115. 'time' => array('name' => 'time'),
  116. 'date' => array('name' => 'date'),
  117. 'binary' => array('name' => 'binary'),
  118. 'boolean' => array('name' => 'boolean')
  119. );
  120. }
  121. }
  122. ?>