AdapterTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. <?php
  2. use ActiveRecord\Column;
  3. class AdapterTest extends DatabaseTest
  4. {
  5. const InvalidDb = '__1337__invalid_db__';
  6. public function set_up($connection_name=null)
  7. {
  8. if (($connection_name && !in_array($connection_name, PDO::getAvailableDrivers())) ||
  9. ActiveRecord\Config::instance()->get_connection($connection_name) == 'skip')
  10. $this->mark_test_skipped($connection_name . ' drivers are not present');
  11. parent::set_up($connection_name);
  12. }
  13. public function test_i_has_a_default_port_unless_im_sqlite()
  14. {
  15. if ($this->conn instanceof ActiveRecord\SqliteAdapter)
  16. return;
  17. $c = $this->conn;
  18. $this->assert_true($c::$DEFAULT_PORT > 0);
  19. }
  20. public function test_should_set_adapter_variables()
  21. {
  22. $this->assert_not_null($this->conn->protocol);
  23. }
  24. public function test_null_connection_string_uses_default_connection()
  25. {
  26. $this->assert_not_null(ActiveRecord\Connection::instance(null));
  27. $this->assert_not_null(ActiveRecord\Connection::instance(''));
  28. $this->assert_not_null(ActiveRecord\Connection::instance());
  29. }
  30. /**
  31. * @expectedException ActiveRecord\DatabaseException
  32. */
  33. public function test_invalid_connection_protocol()
  34. {
  35. ActiveRecord\Connection::instance('terribledb://user:pass@host/db');
  36. }
  37. /**
  38. * @expectedException ActiveRecord\DatabaseException
  39. */
  40. public function test_no_host_connection()
  41. {
  42. if (!$GLOBALS['slow_tests'])
  43. throw new ActiveRecord\DatabaseException("");
  44. ActiveRecord\Connection::instance("{$this->conn->protocol}://user:pass");
  45. }
  46. /**
  47. * @expectedException ActiveRecord\DatabaseException
  48. */
  49. public function test_connection_failed_invalid_host()
  50. {
  51. if (!$GLOBALS['slow_tests'])
  52. throw new ActiveRecord\DatabaseException("");
  53. ActiveRecord\Connection::instance("{$this->conn->protocol}://user:pass/1.1.1.1/db");
  54. }
  55. /**
  56. * @expectedException ActiveRecord\DatabaseException
  57. */
  58. public function test_connection_failed()
  59. {
  60. ActiveRecord\Connection::instance("{$this->conn->protocol}://baduser:[email protected]/db");
  61. }
  62. /**
  63. * @expectedException ActiveRecord\DatabaseException
  64. */
  65. public function test_connect_failed()
  66. {
  67. ActiveRecord\Connection::instance("{$this->conn->protocol}://zzz:[email protected]/test");
  68. }
  69. public function test_connect_with_port()
  70. {
  71. $config = ActiveRecord\Config::instance();
  72. $name = $config->get_default_connection();
  73. $url = parse_url($config->get_connection($name));
  74. $conn = $this->conn;
  75. $port = $conn::$DEFAULT_PORT;
  76. if ($this->conn->protocol != 'sqlite')
  77. ActiveRecord\Connection::instance("{$url['scheme']}://{$url['user']}:{$url['pass']}@{$url['host']}:$port{$url['path']}");
  78. }
  79. /**
  80. * @expectedException ActiveRecord\DatabaseException
  81. */
  82. public function test_connect_to_invalid_database()
  83. {
  84. ActiveRecord\Connection::instance("{$this->conn->protocol}://test:[email protected]/" . self::InvalidDb);
  85. }
  86. public function test_date_time_type()
  87. {
  88. $columns = $this->conn->columns('authors');
  89. $this->assert_equals('datetime',$columns['created_at']->raw_type);
  90. $this->assert_equals(Column::DATETIME,$columns['created_at']->type);
  91. $this->assert_true($columns['created_at']->length > 0);
  92. }
  93. public function test_date()
  94. {
  95. $columns = $this->conn->columns('authors');
  96. $this->assert_equals('date', $columns['some_Date']->raw_type);
  97. $this->assert_equals(Column::DATE, $columns['some_Date']->type);
  98. $this->assert_true($columns['some_Date']->length >= 7);
  99. }
  100. public function test_columns_no_inflection_on_hash_key()
  101. {
  102. $author_columns = $this->conn->columns('authors');
  103. $this->assert_true(array_key_exists('author_id',$author_columns));
  104. }
  105. public function test_columns_nullable()
  106. {
  107. $author_columns = $this->conn->columns('authors');
  108. $this->assert_false($author_columns['author_id']->nullable);
  109. $this->assert_true($author_columns['parent_author_id']->nullable);
  110. }
  111. public function test_columns_pk()
  112. {
  113. $author_columns = $this->conn->columns('authors');
  114. $this->assert_true($author_columns['author_id']->pk);
  115. $this->assert_false($author_columns['parent_author_id']->pk);
  116. }
  117. public function test_columns_sequence()
  118. {
  119. if ($this->conn->supports_sequences())
  120. {
  121. $author_columns = $this->conn->columns('authors');
  122. $this->assert_equals('authors_author_id_seq',$author_columns['author_id']->sequence);
  123. }
  124. }
  125. public function test_columns_default()
  126. {
  127. $author_columns = $this->conn->columns('authors');
  128. $this->assert_equals('default_name',$author_columns['name']->default);
  129. }
  130. public function test_columns_type()
  131. {
  132. $author_columns = $this->conn->columns('authors');
  133. $this->assert_equals('varchar',substr($author_columns['name']->raw_type,0,7));
  134. $this->assert_equals(Column::STRING,$author_columns['name']->type);
  135. $this->assert_equals(25,$author_columns['name']->length);
  136. }
  137. public function test_columns_text()
  138. {
  139. $author_columns = $this->conn->columns('authors');
  140. $this->assert_equals('text',$author_columns['some_text']->raw_type);
  141. $this->assert_equals(null,$author_columns['some_text']->length);
  142. }
  143. public function test_columns_time()
  144. {
  145. $author_columns = $this->conn->columns('authors');
  146. $this->assert_equals('time',$author_columns['some_time']->raw_type);
  147. $this->assert_equals(Column::TIME,$author_columns['some_time']->type);
  148. }
  149. public function test_query()
  150. {
  151. $sth = $this->conn->query('SELECT * FROM authors');
  152. while (($row = $sth->fetch()))
  153. $this->assert_not_null($row);
  154. $sth = $this->conn->query('SELECT * FROM authors WHERE author_id=1');
  155. $row = $sth->fetch();
  156. $this->assert_equals('Tito',$row['name']);
  157. }
  158. /**
  159. * @expectedException ActiveRecord\DatabaseException
  160. */
  161. public function test_invalid_query()
  162. {
  163. $this->conn->query('alsdkjfsdf');
  164. }
  165. public function test_fetch()
  166. {
  167. $sth = $this->conn->query('SELECT * FROM authors WHERE author_id IN(1,2,3)');
  168. $i = 0;
  169. $ids = array();
  170. while (($row = $sth->fetch()))
  171. {
  172. ++$i;
  173. $ids[] = $row['author_id'];
  174. }
  175. $this->assert_equals(3,$i);
  176. $this->assert_equals(array(1,2,3),$ids);
  177. }
  178. public function test_query_with_params()
  179. {
  180. $x=array('Bill Clinton','Tito');
  181. $sth = $this->conn->query('SELECT * FROM authors WHERE name IN(?,?) ORDER BY name DESC',$x);
  182. $row = $sth->fetch();
  183. $this->assert_equals('Tito',$row['name']);
  184. $row = $sth->fetch();
  185. $this->assert_equals('Bill Clinton',$row['name']);
  186. $row = $sth->fetch();
  187. $this->assert_equals(null,$row);
  188. }
  189. public function test_insert_id_should_return_explicitly_inserted_id()
  190. {
  191. $this->conn->query('INSERT INTO authors(author_id,name) VALUES(99,\'name\')');
  192. $this->assert_true($this->conn->insert_id() > 0);
  193. }
  194. public function test_insert_id()
  195. {
  196. $this->conn->query("INSERT INTO authors(name) VALUES('name')");
  197. $this->assert_true($this->conn->insert_id() > 0);
  198. }
  199. public function test_insert_id_with_params()
  200. {
  201. $x = array('name');
  202. $this->conn->query('INSERT INTO authors(name) VALUES(?)',$x);
  203. $this->assert_true($this->conn->insert_id() > 0);
  204. }
  205. public function test_inflection()
  206. {
  207. $columns = $this->conn->columns('authors');
  208. $this->assert_equals('parent_author_id',$columns['parent_author_id']->inflected_name);
  209. }
  210. public function test_escape()
  211. {
  212. $s = "Bob's";
  213. $this->assert_not_equals($s,$this->conn->escape($s));
  214. }
  215. public function test_columnsx()
  216. {
  217. $columns = $this->conn->columns('authors');
  218. $names = array('author_id','parent_author_id','name','updated_at','created_at','some_Date','some_time','some_text','encrypted_password','mixedCaseField');
  219. if ($this->conn instanceof ActiveRecord\OciAdapter)
  220. $names = array_filter(array_map('strtolower',$names),function($s) { $s !== 'some_time'; });
  221. foreach ($names as $field)
  222. $this->assert_true(array_key_exists($field,$columns));
  223. $this->assert_equals(true,$columns['author_id']->pk);
  224. $this->assert_equals('int',$columns['author_id']->raw_type);
  225. $this->assert_equals(Column::INTEGER,$columns['author_id']->type);
  226. $this->assert_true($columns['author_id']->length > 1);
  227. $this->assert_false($columns['author_id']->nullable);
  228. $this->assert_equals(false,$columns['parent_author_id']->pk);
  229. $this->assert_true($columns['parent_author_id']->nullable);
  230. $this->assert_equals('varchar',substr($columns['name']->raw_type,0,7));
  231. $this->assert_equals(Column::STRING,$columns['name']->type);
  232. $this->assert_equals(25,$columns['name']->length);
  233. }
  234. public function test_columns_decimal()
  235. {
  236. $columns = $this->conn->columns('books');
  237. $this->assert_equals(Column::DECIMAL,$columns['special']->type);
  238. $this->assert_true($columns['special']->length >= 10);
  239. }
  240. private function limit($offset, $limit)
  241. {
  242. $ret = array();
  243. $sql = 'SELECT * FROM authors ORDER BY name ASC';
  244. $this->conn->query_and_fetch($this->conn->limit($sql,$offset,$limit),function($row) use (&$ret) { $ret[] = $row; });
  245. return ActiveRecord\collect($ret,'author_id');
  246. }
  247. public function test_limit()
  248. {
  249. $this->assert_equals(array(2,1),$this->limit(1,2));
  250. }
  251. public function test_limit_to_first_record()
  252. {
  253. $this->assert_equals(array(3),$this->limit(0,1));
  254. }
  255. public function test_limit_to_last_record()
  256. {
  257. $this->assert_equals(array(1),$this->limit(2,1));
  258. }
  259. public function test_limit_with_null_offset()
  260. {
  261. $this->assert_equals(array(3),$this->limit(null,1));
  262. }
  263. public function test_limit_with_nulls()
  264. {
  265. $this->assert_equals(array(),$this->limit(null,null));
  266. }
  267. public function test_fetch_no_results()
  268. {
  269. $sth = $this->conn->query('SELECT * FROM authors WHERE author_id=65534');
  270. $this->assert_equals(null,$sth->fetch());
  271. }
  272. public function test_tables()
  273. {
  274. $this->assert_true(count($this->conn->tables()) > 0);
  275. }
  276. public function test_query_column_info()
  277. {
  278. $this->assert_greater_than(0,count($this->conn->query_column_info("authors")));
  279. }
  280. public function test_query_table_info()
  281. {
  282. $this->assert_greater_than(0,count($this->conn->query_for_tables()));
  283. }
  284. public function test_query_table_info_must_return_one_field()
  285. {
  286. $sth = $this->conn->query_for_tables();
  287. $this->assert_equals(1,count($sth->fetch()));
  288. }
  289. public function test_transaction_commit()
  290. {
  291. $original = $this->conn->query_and_fetch_one("select count(*) from authors");
  292. $this->conn->transaction();
  293. $this->conn->query("insert into authors(author_id,name) values(9999,'blahhhhhhhh')");
  294. $this->conn->commit();
  295. $this->assert_equals($original+1,$this->conn->query_and_fetch_one("select count(*) from authors"));
  296. }
  297. public function test_transaction_rollback()
  298. {
  299. $original = $this->conn->query_and_fetch_one("select count(*) from authors");
  300. $this->conn->transaction();
  301. $this->conn->query("insert into authors(author_id,name) values(9999,'blahhhhhhhh')");
  302. $this->conn->rollback();
  303. $this->assert_equals($original,$this->conn->query_and_fetch_one("select count(*) from authors"));
  304. }
  305. public function test_show_me_a_useful_pdo_exception_message()
  306. {
  307. try {
  308. $this->conn->query('select * from an_invalid_column');
  309. $this->fail();
  310. } catch (Exception $e) {
  311. $this->assert_equals(1,preg_match('/(an_invalid_column)|(exist)/',$e->getMessage()));
  312. }
  313. }
  314. public function test_quote_name_does_not_over_quote()
  315. {
  316. $c = $this->conn;
  317. $q = $c::$QUOTE_CHARACTER;
  318. $qn = function($s) use ($c) { return $c->quote_name($s); };
  319. $this->assert_equals("{$q}string", $qn("{$q}string"));
  320. $this->assert_equals("string{$q}", $qn("string{$q}"));
  321. $this->assert_equals("{$q}string{$q}", $qn("{$q}string{$q}"));
  322. }
  323. public function test_datetime_to_string()
  324. {
  325. $datetime = '2009-01-01 01:01:01 EST';
  326. $this->assert_equals($datetime,$this->conn->datetime_to_string(date_create($datetime)));
  327. }
  328. public function test_date_to_string()
  329. {
  330. $datetime = '2009-01-01';
  331. $this->assert_equals($datetime,$this->conn->date_to_string(date_create($datetime)));
  332. }
  333. }
  334. ?>