Improve float and integer handling

This commit is contained in:
Maurits van der Schee 2016-11-30 01:07:56 +01:00
commit 8616b6795b
7 changed files with 174 additions and 82 deletions

66
api.php
View file

@ -5,8 +5,8 @@ interface DatabaseInterface {
public function getSql($name);
public function connect($hostname,$username,$password,$database,$port,$socket,$charset);
public function query($sql,$params=array());
public function fetchAssoc($result);
public function fetchRow($result);
public function fetchAssoc($result,$fields=false);
public function fetchRow($result,$fields=false);
public function insertId($result);
public function affectedRows($result);
public function close($result);
@ -104,6 +104,9 @@ class MySQL implements DatabaseInterface {
if (!mysqli_query($db,'SET SESSION sql_mode = \'ANSI_QUOTES\';')) {
throw new \Exception('Error setting ANSI quotes. '.mysqli_error($db));
}
if (!mysqli_options($db,MYSQLI_OPT_INT_AND_FLOAT_NATIVE,true)) {
throw new \Exception('Error setting int and float native. '.mysqli_error($db));
}
$this->db = $db;
}
@ -138,11 +141,11 @@ class MySQL implements DatabaseInterface {
return mysqli_query($db,$sql);
}
public function fetchAssoc($result) {
public function fetchAssoc($result,$fields=false) {
return mysqli_fetch_assoc($result);
}
public function fetchRow($result) {
public function fetchRow($result,$fields=false) {
return mysqli_fetch_row($result);
}
@ -365,12 +368,29 @@ class PostgreSQL implements DatabaseInterface {
return @pg_query($db,$sql);
}
public function fetchAssoc($result) {
return pg_fetch_assoc($result);
protected function convertFloatAndInt($result,&$values, $fields) {
array_walk($values, function(&$v,$i) use ($result,$fields){
$t = $fields[$i]->type;
if (is_string($v) && in_array($t,array('int2','int4','int8','float4','float8'))) {
$v+=0;
}
});
}
public function fetchRow($result) {
return pg_fetch_row($result);
public function fetchAssoc($result,$fields=false) {
$values = pg_fetch_assoc($result);
if ($values && $fields) {
$this->convertFloatAndInt($result,$values,$fields);
}
return $values;
}
public function fetchRow($result,$fields=false) {
$values = pg_fetch_row($result);
if ($values && $fields) {
$this->convertFloatAndInt($result,$values,array_values($fields));
}
return $values;
}
public function insertId($result) {
@ -591,16 +611,12 @@ class SQLServer implements DatabaseInterface {
return sqlsrv_query($db,$sql,$args)?:null;
}
public function fetchAssoc($result) {
$values = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC);
if ($values) $values = array_map(function($v){ return is_null($v)?null:(string)$v; },$values);
return $values;
public function fetchAssoc($result,$fields=false) {
return sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC);
}
public function fetchRow($result) {
$values = sqlsrv_fetch_array($result, SQLSRV_FETCH_NUMERIC);
if ($values) $values = array_map(function($v){ return is_null($v)?null:(string)$v; },$values);
return $values;
public function fetchRow($result,$fields=false) {
return sqlsrv_fetch_array($result, SQLSRV_FETCH_NUMERIC);
}
public function insertId($result) {
@ -832,16 +848,12 @@ class SQLite implements DatabaseInterface {
return $result;
}
public function fetchAssoc($result) {
$values = $result->fetchArray(SQLITE3_ASSOC);
if ($values) $values = array_map(function($v){ return is_null($v)?null:(string)$v; },$values);
return $values;
public function fetchAssoc($result,$fields=false) {
return $result->fetchArray(SQLITE3_ASSOC);
}
public function fetchRow($result) {
$values = $result->fetchArray(SQLITE3_NUM);
if ($values) $values = array_map(function($v){ return is_null($v)?null:(string)$v; },$values);
return $values;
public function fetchRow($result,$fields=false) {
return $result->fetchArray(SQLITE3_NUM);
}
public function insertId($result) {
@ -1240,7 +1252,7 @@ class PHP_CRUD_API {
$this->addWhereFromFilters($filters[$table],$sql,$params);
$object = null;
if ($result = $this->db->query($sql,$params)) {
$object = $this->db->fetchAssoc($result);
$object = $this->db->fetchAssoc($result,$fields[$table]);
$this->db->close($result);
}
return $object;
@ -1625,7 +1637,7 @@ class PHP_CRUD_API {
$keys = array_flip($keys);
echo ',"records":[';
$first_row = true;
while ($row = $this->db->fetchRow($result)) {
while ($row = $this->db->fetchRow($result,$fields[$table])) {
if ($first_row) $first_row = false;
else echo ',';
if (isset($collect[$table])) {
@ -1675,7 +1687,7 @@ class PHP_CRUD_API {
$keys = array_flip($keys);
echo ',"records":[';
$first_row = true;
while ($row = $this->db->fetchRow($result)) {
while ($row = $this->db->fetchRow($result,$fields[$table])) {
if ($first_row) $first_row = false;
else echo ',';
if (isset($collect[$table])) {

Binary file not shown.

View file

@ -118,4 +118,15 @@ INSERT INTO `events` (`id`, `name`, `datetime`) VALUES
DROP VIEW IF EXISTS `tag_usage`;
CREATE VIEW `tag_usage` AS select `name`, count(`name`) AS `count` from `tags`, `post_tags` where `tags`.`id` = `post_tags`.`tag_id` group by `name` order by `count` desc, `name`;
DROP TABLE IF EXISTS `products`;
CREATE TABLE `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`price` decimal(10,2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `products` (`id`, `name`, `price`) VALUES
(1, 'Calculator', '23.01');
-- 2016-11-05 13:11:47

View file

@ -28,6 +28,8 @@ DROP TABLE IF EXISTS users CASCADE;
DROP TABLE IF EXISTS countries CASCADE;
DROP TABLE IF EXISTS events CASCADE;
DROP VIEW IF EXISTS tag_usage;
DROP TABLE IF EXISTS products CASCADE;
--
-- Name: categories; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
--
@ -120,6 +122,16 @@ CREATE TABLE events (
CREATE VIEW "tag_usage" AS select "name", count("name") AS "count" from "tags", "post_tags" where "tags"."id" = "post_tags"."tag_id" group by "name" order by "count" desc, "name";
--
-- Name: products; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
--
CREATE TABLE products (
id serial NOT NULL,
name character varying(255) NOT NULL,
price decimal(10,2) NOT NULL
);
--
-- Data for Name: categories; Type: TABLE DATA; Schema: public; Owner: postgres
--
@ -187,6 +199,13 @@ INSERT INTO "countries" ("name", "shape") VALUES
INSERT INTO "events" ("name", "datetime") VALUES
('Launch', '2016-01-01 13:01:01.111');
--
-- Data for Name: events; Type: TABLE DATA; Schema: public; Owner: postgres
--
INSERT INTO "products" ("name", "price") VALUES
('Calculator', '23.01');
--
-- Name: categories_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
--
@ -258,6 +277,14 @@ ALTER TABLE ONLY events
ADD CONSTRAINT events_pkey PRIMARY KEY (id);
--
-- Name: products_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
--
ALTER TABLE ONLY products
ADD CONSTRAINT products_pkey PRIMARY KEY (id);
--
-- Name: comments_post_id_idx; Type: INDEX; Schema: public; Owner: postgres; Tablespace:
--

View file

@ -100,4 +100,13 @@ INSERT INTO `events` (`id`, `name`, `datetime`) VALUES (1, 'Launch', '2016-01-01
DROP VIEW IF EXISTS `tag_usage`;
CREATE VIEW `tag_usage` AS select `name`, count(`name`) AS `count` from `tags`, `post_tags` where `tags`.`id` = `post_tags`.`tag_id` group by `name` order by `count` desc, `name`;
DROP TABLE IF EXISTS `products`;
CREATE TABLE `products` (
`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT,
`name` text(255) NOT NULL,
`price` text(12) NOT NULL
);
INSERT INTO `products` (`id`, `name`, `price`) VALUES (1, 'Calculator', '23.01');
--

View file

@ -23,6 +23,11 @@ BEGIN
ALTER TABLE [comments] DROP CONSTRAINT [FK_comments_posts]
END
GO
IF (OBJECT_ID('products', 'U') IS NOT NULL)
BEGIN
DROP TABLE [products]
END
GO
IF (OBJECT_ID('events', 'U') IS NOT NULL)
BEGIN
DROP TABLE [events]
@ -193,6 +198,21 @@ CREATE VIEW [tag_usage]
AS
SELECT top 100 PERCENT name, COUNT(name) AS [count] FROM tags, post_tags WHERE tags.id = post_tags.tag_id GROUP BY name ORDER BY [count] DESC, name
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [products](
[id] [int] IDENTITY,
[name] [nvarchar](max) NOT NULL,
[price] [decimal](10,2) NOT NULL,
CONSTRAINT [PK_products] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET IDENTITY_INSERT [categories] ON
GO
@ -264,6 +284,12 @@ INSERT [events] ([id], [name], [datetime]) VALUES (1, N'Launch', N'2016-01-01 13
GO
SET IDENTITY_INSERT [events] OFF
GO
SET IDENTITY_INSERT [products] ON
GO
INSERT [products] ([id], [name], [price]) VALUES (1, N'Calculator', N'23.01')
GO
SET IDENTITY_INSERT [products] OFF
GO
ALTER TABLE [comments] WITH CHECK ADD CONSTRAINT [FK_comments_posts] FOREIGN KEY([post_id])
REFERENCES [posts] ([id])
GO

View file

@ -192,58 +192,58 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
{
$test = new API($this);
$test->get('/posts');
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[["1","1","1","blog started"],["2","1","2","It works!"]]}}');
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[1,1,1,"blog started"],[2,1,2,"It works!"]]}}');
}
public function testListPostColumns()
{
$test = new API($this);
$test->get('/posts?columns=id,content');
$test->expect('{"posts":{"columns":["id","content"],"records":[["1","blog started"],["2","It works!"]]}}');
$test->expect('{"posts":{"columns":["id","content"],"records":[[1,"blog started"],[2,"It works!"]]}}');
}
public function testListPostsWithTransform()
{
$test = new API($this);
$test->get('/posts?transform=1');
$test->expect('{"posts":[{"id":"1","user_id":"1","category_id":"1","content":"blog started"},{"id":"2","user_id":"1","category_id":"2","content":"It works!"}]}');
$test->expect('{"posts":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"},{"id":2,"user_id":1,"category_id":2,"content":"It works!"}]}');
}
public function testReadPost()
{
$test = new API($this);
$test->get('/posts/2');
$test->expect('{"id":"2","user_id":"1","category_id":"2","content":"It works!"}');
$test->expect('{"id":2,"user_id":1,"category_id":2,"content":"It works!"}');
}
public function testReadPosts()
{
$test = new API($this);
$test->get('/posts/1,2');
$test->expect('[{"id":"1","user_id":"1","category_id":"1","content":"blog started"},{"id":"2","user_id":"1","category_id":"2","content":"It works!"}]');
$test->expect('[{"id":1,"user_id":1,"category_id":1,"content":"blog started"},{"id":2,"user_id":1,"category_id":2,"content":"It works!"}]');
}
public function testReadPostColumns()
{
$test = new API($this);
$test->get('/posts/2?columns=id,content');
$test->expect('{"id":"2","content":"It works!"}');
$test->expect('{"id":2,"content":"It works!"}');
}
public function testAddPost()
{
$test = new API($this);
$test->post('/posts','{"user_id":"1","category_id":"1","content":"test"}');
$test->post('/posts','{"user_id":1,"category_id":1,"content":"test"}');
$test->expect('3');
}
public function testEditPost()
{
$test = new API($this);
$test->put('/posts/3','{"user_id":"1","category_id":"1","content":"test (edited)"}');
$test->put('/posts/3','{"user_id":1,"category_id":1,"content":"test (edited)"}');
$test->expect('1');
$test->get('/posts/3');
$test->expect('{"id":"3","user_id":"1","category_id":"1","content":"test (edited)"}');
$test->expect('{"id":3,"user_id":1,"category_id":1,"content":"test (edited)"}');
}
public function testEditPostColumnsMissingField()
@ -252,16 +252,16 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/posts/3?columns=id,content','{"content":"test (edited 2)"}');
$test->expect('1');
$test->get('/posts/3');
$test->expect('{"id":"3","user_id":"1","category_id":"1","content":"test (edited 2)"}');
$test->expect('{"id":3,"user_id":1,"category_id":1,"content":"test (edited 2)"}');
}
public function testEditPostColumnsExtraField()
{
$test = new API($this);
$test->put('/posts/3?columns=id,content','{"user_id":"2","content":"test (edited 3)"}');
$test->put('/posts/3?columns=id,content','{"user_id":2,"content":"test (edited 3)"}');
$test->expect('1');
$test->get('/posts/3');
$test->expect('{"id":"3","user_id":"1","category_id":"1","content":"test (edited 3)"}');
$test->expect('{"id":3,"user_id":1,"category_id":1,"content":"test (edited 3)"}');
}
public function testEditPostWithUtf8Content()
@ -271,7 +271,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/posts/2','{"content":'.$utf8.'}');
$test->expect('1');
$test->get('/posts/2');
$test->expect('{"id":"2","user_id":"1","category_id":"2","content":'.$utf8.'}');
$test->expect('{"id":2,"user_id":1,"category_id":2,"content":'.$utf8.'}');
}
public function testEditPostWithUtf8ContentWithPost()
@ -283,7 +283,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/posts/2','content='.$url_encoded);
$test->expect('1');
$test->get('/posts/2');
$test->expect('{"id":"2","user_id":"1","category_id":"2","content":'.$json_encoded.'}');
$test->expect('{"id":2,"user_id":1,"category_id":2,"content":'.$json_encoded.'}');
}
public function testDeletePost()
@ -308,7 +308,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/posts/4','user_id=1&category_id=1&content=test+(edited)');
$test->expect('1');
$test->get('/posts/4');
$test->expect('{"id":"4","user_id":"1","category_id":"1","content":"test (edited)"}');
$test->expect('{"id":4,"user_id":1,"category_id":1,"content":"test (edited)"}');
}
public function testDeletePostWithPost()
@ -324,32 +324,32 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
{
$test = new API($this);
for ($i=1;$i<=10;$i++) {
$test->post('/posts','{"user_id":"1","category_id":"1","content":"#'.$i.'"}');
$test->post('/posts','{"user_id":1,"category_id":1,"content":"#'.$i.'"}');
$test->expect(4+$i);
}
$test->get('/posts?page=2,2&order=id');
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[["5","1","1","#1"],["6","1","1","#2"]],"results":11}}');
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[5,1,1,"#1"],[6,1,1,"#2"]],"results":11}}');
}
public function testListWithPaginateLastPage()
{
$test = new API($this);
$test->get('/posts?page=3,5&order=id');
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[["14","1","1","#10"]],"results":11}}');
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[14,1,1,"#10"]],"results":11}}');
}
public function testListExampleFromReadme()
{
$test = new API($this);
$test->get('/posts?include=categories,tags,comments&filter=id,eq,1');
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[["1","1","1","blog started"]]},"post_tags":{"relations":{"post_id":"posts.id"},"columns":["id","post_id","tag_id"],"records":[["1","1","1"],["2","1","2"]]},"categories":{"relations":{"id":"posts.category_id"},"columns":["id","name","icon"],"records":[["1","announcement",null]]},"tags":{"relations":{"id":"post_tags.tag_id"},"columns":["id","name"],"records":[["1","funny"],["2","important"]]},"comments":{"relations":{"post_id":"posts.id"},"columns":["id","post_id","message"],"records":[["1","1","great"],["2","1","fantastic"]]}}');
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[1,1,1,"blog started"]]},"post_tags":{"relations":{"post_id":"posts.id"},"columns":["id","post_id","tag_id"],"records":[[1,1,1],[2,1,2]]},"categories":{"relations":{"id":"posts.category_id"},"columns":["id","name","icon"],"records":[[1,"announcement",null]]},"tags":{"relations":{"id":"post_tags.tag_id"},"columns":["id","name"],"records":[[1,"funny"],[2,"important"]]},"comments":{"relations":{"post_id":"posts.id"},"columns":["id","post_id","message"],"records":[[1,1,"great"],[2,1,"fantastic"]]}}');
}
public function testListExampleFromReadmeWithTransform()
{
$test = new API($this);
$test->get('/posts?include=categories,tags,comments&filter=id,eq,1&transform=1');
$test->expect('{"posts":[{"id":"1","post_tags":[{"id":"1","post_id":"1","tag_id":"1","tags":[{"id":"1","name":"funny"}]},{"id":"2","post_id":"1","tag_id":"2","tags":[{"id":"2","name":"important"}]}],"comments":[{"id":"1","post_id":"1","message":"great"},{"id":"2","post_id":"1","message":"fantastic"}],"user_id":"1","category_id":"1","categories":[{"id":"1","name":"announcement","icon":null}],"content":"blog started"}]}');
$test->expect('{"posts":[{"id":1,"post_tags":[{"id":1,"post_id":1,"tag_id":1,"tags":[{"id":1,"name":"funny"}]},{"id":2,"post_id":1,"tag_id":2,"tags":[{"id":2,"name":"important"}]}],"comments":[{"id":1,"post_id":1,"message":"great"},{"id":2,"post_id":1,"message":"fantastic"}],"user_id":1,"category_id":1,"categories":[{"id":1,"name":"announcement","icon":null}],"content":"blog started"}]}');
}
public function testEditCategoryWithBinaryContent()
@ -360,7 +360,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/categories/2','{"icon":"'.$base64url.'"}');
$test->expect('1');
$test->get('/categories/2');
$test->expect('{"id":"2","name":"article","icon":"'.$binary.'"}');
$test->expect('{"id":2,"name":"article","icon":"'.$binary.'"}');
}
public function testEditCategoryWithNull()
@ -369,7 +369,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/categories/2','{"icon":null}');
$test->expect('1');
$test->get('/categories/2');
$test->expect('{"id":"2","name":"article","icon":null}');
$test->expect('{"id":2,"name":"article","icon":null}');
}
public function testEditCategoryWithBinaryContentWithPost()
@ -380,14 +380,14 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/categories/2','icon='.$base64url);
$test->expect('1');
$test->get('/categories/2');
$test->expect('{"id":"2","name":"article","icon":"'.$binary.'"}');
$test->expect('{"id":2,"name":"article","icon":"'.$binary.'"}');
}
public function testListCategoriesWithBinaryContent()
{
$test = new API($this);
$test->get('/categories');
$test->expect('{"categories":{"columns":["id","name","icon"],"records":[["1","announcement",null],["2","article","4oKsIABhYmMACg1cYgA="]]}}');
$test->expect('{"categories":{"columns":["id","name","icon"],"records":[[1,"announcement",null],[2,"article","4oKsIABhYmMACg1cYgA="]]}}');
}
public function testEditCategoryWithNullWithPost()
@ -396,13 +396,13 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/categories/2','icon__is_null');
$test->expect('1');
$test->get('/categories/2');
$test->expect('{"id":"2","name":"article","icon":null}');
$test->expect('{"id":2,"name":"article","icon":null}');
}
public function testAddPostFailure()
{
$test = new API($this);
$test->post('/posts','{"user_id":"a","category_id":"1","content":"tests"}');
$test->post('/posts','{"user_id":"a","category_id":1,"content":"tests"}');
$test->expect('null');
}
@ -417,7 +417,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
{
$test = new API($this);
$test->get('/users?filter=id,eq,1&transform=1');
$test->expect('{"users":[{"id":"1","username":"user1","location":null}]}');
$test->expect('{"users":[{"id":1,"username":"user1","location":null}]}');
}
public function testValidatorErrorMessage()
@ -433,7 +433,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/categories/2','{"name":"<script>alert();</script>"}');
$test->expect('1');
$test->get('/categories/2');
$test->expect('{"id":"2","name":"alert();","icon":null}');
$test->expect('{"id":2,"name":"alert();","icon":null}');
}
public function testErrorOnInvalidJson()
@ -446,14 +446,14 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
public function testErrorOnDuplicatePrimaryKey()
{
$test = new API($this);
$test->post('/posts','{"id":"1","user_id":"1","category_id":"1","content":"blog started (duplicate)"}');
$test->post('/posts','{"id":1,"user_id":1,"category_id":1,"content":"blog started (duplicate)"}');
$test->expect('null');
}
public function testErrorOnFailingForeignKeyConstraint()
{
$test = new API($this);
$test->post('/posts','{"user_id":"3","category_id":"1","content":"fk constraint"}');
$test->post('/posts','{"user_id":3,"category_id":1,"content":"fk constraint"}');
$test->expect('null');
}
@ -461,7 +461,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
{
$test = new API($this);
$test->get('/users?include=posts,tags');
$test->expect('{"users":{"columns":["id","username","location"],"records":[["1","user1",null]]},"posts":{"relations":{"user_id":"users.id"},"columns":["id","user_id","category_id","content"],"records":[["1","1","1","blog started"],["2","1","2","\u20ac Hello world, \u039a\u03b1\u03bb\u03b7\u03bc\u1f73\u03c1\u03b1 \u03ba\u1f79\u03c3\u03bc\u03b5, \u30b3\u30f3\u30cb\u30c1\u30cf"],["5","1","1","#1"],["6","1","1","#2"],["7","1","1","#3"],["8","1","1","#4"],["9","1","1","#5"],["10","1","1","#6"],["11","1","1","#7"],["12","1","1","#8"],["14","1","1","#10"]]},"post_tags":{"relations":{"post_id":"posts.id"},"columns":["id","post_id","tag_id"],"records":[["1","1","1"],["2","1","2"],["3","2","1"],["4","2","2"]]},"tags":{"relations":{"id":"post_tags.tag_id"},"columns":["id","name"],"records":[["1","funny"],["2","important"]]}}');
$test->expect('{"users":{"columns":["id","username","location"],"records":[[1,"user1",null]]},"posts":{"relations":{"user_id":"users.id"},"columns":["id","user_id","category_id","content"],"records":[[1,1,1,"blog started"],[2,1,2,"\u20ac Hello world, \u039a\u03b1\u03bb\u03b7\u03bc\u1f73\u03c1\u03b1 \u03ba\u1f79\u03c3\u03bc\u03b5, \u30b3\u30f3\u30cb\u30c1\u30cf"],[5,1,1,"#1"],[6,1,1,"#2"],[7,1,1,"#3"],[8,1,1,"#4"],[9,1,1,"#5"],[10,1,1,"#6"],[11,1,1,"#7"],[12,1,1,"#8"],[14,1,1,"#10"]]},"post_tags":{"relations":{"post_id":"posts.id"},"columns":["id","post_id","tag_id"],"records":[[1,1,1],[2,1,2],[3,2,1],[4,2,2]]},"tags":{"relations":{"id":"post_tags.tag_id"},"columns":["id","name"],"records":[[1,"funny"],[2,"important"]]}}');
}
public function testEditUserPassword()
@ -478,9 +478,9 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->expect('1');
$test->get('/users/1?columns=id,location');
if (PHP_CRUD_API_Config::$dbengine=='SQLServer') {
$test->expect('{"id":"1","location":"POINT (30 20)"}');
$test->expect('{"id":1,"location":"POINT (30 20)"}');
} else {
$test->expect('{"id":"1","location":"POINT(30 20)"}');
$test->expect('{"id":1,"location":"POINT(30 20)"}');
}
}
@ -489,9 +489,9 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test = new API($this);
$test->get('/users?columns=id,location');
if (PHP_CRUD_API_Config::$dbengine=='SQLServer') {
$test->expect('{"users":{"columns":["id","location"],"records":[["1","POINT (30 20)"]]}}');
$test->expect('{"users":{"columns":["id","location"],"records":[[1,"POINT (30 20)"]]}}');
} else {
$test->expect('{"users":{"columns":["id","location"],"records":[["1","POINT(30 20)"]]}}');
$test->expect('{"users":{"columns":["id","location"],"records":[[1,"POINT(30 20)"]]}}');
}
}
@ -499,10 +499,10 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
{
if (PHP_CRUD_API_Config::$dbengine!='SQLServer') {
$test = new API($this);
$test->put('/users/1','{"id":"2","password":"testtest2"}');
$test->put('/users/1','{"id":2,"password":"testtest2"}');
$test->expect('1');
$test->get('/users/1?columns=id,username,password');
$test->expect('{"id":"1","username":"user1","password":"testtest2"}');
$test->expect('{"id":1,"username":"user1","password":"testtest2"}');
}
}
@ -524,7 +524,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
{
$test = new API($this);
$test->get('/categories?filter[]=icon,is,null&transform=1');
$test->expect('{"categories":[{"id":"1","name":"announcement","icon":null},{"id":"2","name":"alert();","icon":null}]}');
$test->expect('{"categories":[{"id":1,"name":"announcement","icon":null},{"id":2,"name":"alert();","icon":null}]}');
}
public function testFilterCategoryOnNotNullIcon()
@ -538,21 +538,21 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
{
$test = new API($this);
$test->get('/posts?filter[]=id,nin,1,2,3,4,7,8,9,10,11,12,13,14&transform=1');
$test->expect('{"posts":[{"id":"5","user_id":"1","category_id":"1","content":"#1"},{"id":"6","user_id":"1","category_id":"1","content":"#2"}]}');
$test->expect('{"posts":[{"id":5,"user_id":1,"category_id":1,"content":"#1"},{"id":6,"user_id":1,"category_id":1,"content":"#2"}]}');
}
public function testFilterPostsBetween()
{
$test = new API($this);
$test->get('/posts?filter[]=id,bt,5,6&transform=1');
$test->expect('{"posts":[{"id":"5","user_id":"1","category_id":"1","content":"#1"},{"id":"6","user_id":"1","category_id":"1","content":"#2"}]}');
$test->expect('{"posts":[{"id":5,"user_id":1,"category_id":1,"content":"#1"},{"id":6,"user_id":1,"category_id":1,"content":"#2"}]}');
}
public function testFilterPostsNotBetween()
{
$test = new API($this);
$test->get('/posts?filter[]=id,nbt,2,13&transform=1');
$test->expect('{"posts":[{"id":"1","user_id":"1","category_id":"1","content":"blog started"},{"id":"14","user_id":"1","category_id":"1","content":"#10"}]}');
$test->expect('{"posts":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"},{"id":14,"user_id":1,"category_id":1,"content":"#10"}]}');
}
public function testColumnsWithTable()
@ -566,42 +566,42 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
{
$test = new API($this);
$test->get('/posts?columns=posts.*&filter=id,eq,1&transform=1');
$test->expect('{"posts":[{"id":"1","user_id":"1","category_id":"1","content":"blog started"}]}');
$test->expect('{"posts":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"}]}');
}
public function testColumnsOnInclude()
{
$test = new API($this);
$test->get('/posts?include=categories&columns=categories.name&filter=id,eq,1&transform=1');
$test->expect('{"posts":[{"category_id":"1","categories":[{"id":"1","name":"announcement"}]}]}');
$test->expect('{"posts":[{"category_id":1,"categories":[{"id":1,"name":"announcement"}]}]}');
}
public function testFilterOnRelationAnd()
{
$test = new API($this);
$test->get('/categories?include=posts&filter[]=id,ge,1&filter[]=id,le,1&filter[]=id,le,2&filter[]=posts.id,lt,8&filter[]=posts.id,gt,4');
$test->expect('{"categories":{"columns":["id","name","icon"],"records":[["1","announcement",null]]},"posts":{"relations":{"category_id":"categories.id"},"columns":["id","user_id","category_id","content"],"records":[["5","1","1","#1"],["6","1","1","#2"],["7","1","1","#3"]]}}');
$test->expect('{"categories":{"columns":["id","name","icon"],"records":[[1,"announcement",null]]},"posts":{"relations":{"category_id":"categories.id"},"columns":["id","user_id","category_id","content"],"records":[[5,1,1,"#1"],[6,1,1,"#2"],[7,1,1,"#3"]]}}');
}
public function testFilterOnRelationOr()
{
$test = new API($this);
$test->get('/categories?include=posts&filter[]=id,ge,1&filter[]=id,le,1&filter[]=posts.id,eq,5&filter[]=posts.id,eq,6&filter[]=posts.id,eq,7&satisfy=all,posts.any');
$test->expect('{"categories":{"columns":["id","name","icon"],"records":[["1","announcement",null]]},"posts":{"relations":{"category_id":"categories.id"},"columns":["id","user_id","category_id","content"],"records":[["5","1","1","#1"],["6","1","1","#2"],["7","1","1","#3"]]}}');
$test->expect('{"categories":{"columns":["id","name","icon"],"records":[[1,"announcement",null]]},"posts":{"relations":{"category_id":"categories.id"},"columns":["id","user_id","category_id","content"],"records":[[5,1,1,"#1"],[6,1,1,"#2"],[7,1,1,"#3"]]}}');
}
public function testColumnsOnWrongInclude()
{
$test = new API($this);
$test->get('/posts?include=categories&columns=categories&filter=id,eq,1&transform=1');
$test->expect('{"posts":[{"category_id":"1","categories":[{"id":"1"}]}]}');
$test->expect('{"posts":[{"category_id":1,"categories":[{"id":1}]}]}');
}
public function testColumnsOnImplicitJoin()
{
$test = new API($this);
$test->get('/posts?include=tags&columns=posts.id,tags.name&filter=id,eq,1&transform=1');
$test->expect('{"posts":[{"id":"1","post_tags":[{"post_id":"1","tag_id":"1","tags":[{"id":"1","name":"funny"}]},{"post_id":"1","tag_id":"2","tags":[{"id":"2","name":"important"}]}]}]}');
$test->expect('{"posts":[{"id":1,"post_tags":[{"post_id":1,"tag_id":1,"tags":[{"id":1,"name":"funny"}]},{"post_id":1,"tag_id":2,"tags":[{"id":2,"name":"important"}]}]}]}');
}
public function testSpatialFilterWithin()
@ -609,14 +609,14 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
if (PHP_CRUD_API_Config::$dbengine!='SQLite') {
$test = new API($this);
$test->get('/users?columns=id,username&filter=location,swi,POINT(30 20)');
$test->expect('{"users":{"columns":["id","username"],"records":[["1","user1"]]}}');
$test->expect('{"users":{"columns":["id","username"],"records":[[1,"user1"]]}}');
}
}
public function testAddPostsWithNonExistingCategory()
{
$test = new API($this);
$test->post('/posts','[{"user_id":"1","category_id":"1","content":"tests"},{"user_id":"1","category_id":"15","content":"tests"}]');
$test->post('/posts','[{"user_id":1,"category_id":1,"content":"tests"},{"user_id":1,"category_id":15,"content":"tests"}]');
$test->expect('null');
$test->get('/posts?columns=content&filter=content,eq,tests');
$test->expect('{"posts":{"columns":["content"],"records":[]}}');
@ -625,7 +625,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
public function testAddPosts()
{
$test = new API($this);
$test->post('/posts','[{"user_id":"1","category_id":"1","content":"tests"},{"user_id":"1","category_id":"1","content":"tests"}]');
$test->post('/posts','[{"user_id":1,"category_id":1,"content":"tests"},{"user_id":1,"category_id":1,"content":"tests"}]');
$test->expectAny();
$test->get('/posts?columns=content&filter=content,eq,tests');
$test->expect('{"posts":{"columns":["content"],"records":[["tests"],["tests"]]}}');
@ -642,14 +642,14 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
{
$test = new API($this);
$test->get('/tag_usage');
$test->expect('{"tag_usage":{"columns":["name","count"],"records":[["funny","2"],["important","2"]]}}');
$test->expect('{"tag_usage":{"columns":["name","count"],"records":[["funny",2],["important",2]]}}');
}
public function testUpdateMultipleTags()
{
$test = new API($this);
$test->get('/tags?transform=1');
$test->expect('{"tags":[{"id":"1","name":"funny"},{"id":"2","name":"important"}]}');
$test->expect('{"tags":[{"id":1,"name":"funny"},{"id":2,"name":"important"}]}');
$test->put('/tags/1,2','[{"name":"funny"},{"name":"important"}]');
$test->expect('[1,1]');
}
@ -660,7 +660,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/tags/1,2,3','[{"name":"funny!!!"},{"name":"important"}]');
$test->expect(false,'Not found (subject)');
$test->get('/tags?transform=1');
$test->expect('{"tags":[{"id":"1","name":"funny"},{"id":"2","name":"important"}]}');
$test->expect('{"tags":[{"id":1,"name":"funny"},{"id":2,"name":"important"}]}');
}
public function testUpdateMultipleTagsWithoutFields()
@ -669,7 +669,7 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->put('/tags/1,2','[{"name":"funny!!!"},{}]');
$test->expect('null');
$test->get('/tags?transform=1');
$test->expect('{"tags":[{"id":"1","name":"funny"},{"id":"2","name":"important"}]}');
$test->expect('{"tags":[{"id":1,"name":"funny"},{"id":2,"name":"important"}]}');
}
public function testDeleteMultipleTags()
@ -680,6 +680,13 @@ class PHP_CRUD_API_Test extends PHPUnit_Framework_TestCase
$test->delete('/tags/3,4');
$test->expect('[1,1]');
$test->get('/tags?transform=1');
$test->expect('{"tags":[{"id":"1","name":"funny"},{"id":"2","name":"important"}]}');
$test->expect('{"tags":[{"id":1,"name":"funny"},{"id":2,"name":"important"}]}');
}
public function testListProducts()
{
$test = new API($this);
$test->get('/products?transform=1');
$test->expect('{"products":[{"id":1,"name":"Calculator","price":"23.01"}]}');
}
}