@@ -59,73 +59,90 @@ public function getById(string $blogId): Blog
5959 }
6060
6161 public function getBlogs (
62- BlogStatus $ status ,
63- string $ authorId ,
62+ ? BlogStatus $ status ,
63+ ? string $ authorId ,
6464 ?int $ first ,
6565 ?string $ afterCursor ,
6666 ?int $ last ,
6767 ?string $ beforeCursor ,
6868 ): Blogs {
69+ if ($ first !== null && $ last !== null ) {
70+ throw new RuntimeException ('Cannot use both first and last ' );
71+ }
72+
6973 $ sqlite = $ this ->sqliteFactory ->create ();
70- $ direction = $ last !== null && $ beforeCursor !== null ? self ::DIRECTION_BACKWARD : self ::DIRECTION_FORWARD ;
7174
72- if ($ direction === self ::DIRECTION_BACKWARD ) {
75+ $ direction = $ first !== null ? self ::DIRECTION_FORWARD : self ::DIRECTION_BACKWARD ;
76+
77+ $ whereStatements = [];
78+ $ binds = [];
79+
80+ if ($ status !== null ) {
81+ $ whereStatements [] = 'status = :status ' ;
82+ $ binds ['status ' ] = $ status ->value ;
83+ }
84+
85+ if ($ authorId !== null ) {
86+ $ whereStatements [] = 'author_id = :author_id ' ;
87+ $ binds ['author_id ' ] = $ authorId ;
88+ }
89+
90+ $ limit = '' ;
91+
92+ if ($ first !== null ) {
93+ $ limit = 'LIMIT :limit ' ;
94+ $ binds ['limit ' ] = $ first ;
95+ } elseif ($ last !== null ) {
96+ $ limit = 'LIMIT :limit ' ;
97+ $ binds ['limit ' ] = $ last ;
98+ }
99+
100+ if ($ afterCursor !== null ) {
101+ $ whereStatements [] = 'id < :after_cursor ' ;
102+ $ binds ['after_cursor ' ] = $ afterCursor ;
103+ }
104+
105+ if ($ beforeCursor !== null ) {
106+ $ whereStatements [] = 'id > :before_cursor ' ;
107+ $ binds ['before_cursor ' ] = $ beforeCursor ;
108+ }
109+
110+ $ where = '' ;
111+
112+ if ($ whereStatements !== []) {
113+ $ where = sprintf ('WHERE %s ' , implode (' AND ' , $ whereStatements ));
114+ }
115+
116+ if ($ direction === self ::DIRECTION_FORWARD ) {
117+ $ statement = $ sqlite ->prepare (
118+ <<<SQL
119+ SELECT *
120+ FROM blog
121+ {$ where }
122+ ORDER BY id DESC
123+ {$ limit }
124+ SQL
125+ );
126+ } else {
73127 $ statement = $ sqlite ->prepare (
74- <<<' SQL'
128+ <<<SQL
75129 SELECT * FROM (
76130 SELECT *
77131 FROM blog
78- WHERE status = :status
79- AND author_id = :author_id
80- AND id > :cursor
132+ {$ where }
81133 ORDER BY id ASC
82- LIMIT : limit
134+ { $ limit}
83135 ) ORDER BY id DESC
84136 SQL
85137 );
86- } else {
87- if ($ afterCursor === null ) {
88- $ statement = $ sqlite ->prepare (
89- <<<'SQL'
90- SELECT *
91- FROM blog
92- WHERE status = :status
93- AND author_id = :author_id
94- ORDER BY id DESC
95- LIMIT :limit
96- SQL
97- );
98- } else {
99- $ statement = $ sqlite ->prepare (
100- <<<'SQL'
101- SELECT *
102- FROM blog
103- WHERE status = :status
104- AND author_id = :author_id
105- AND id < :cursor
106- ORDER BY id DESC
107- LIMIT :limit
108- SQL
109- );
110- }
111138 }
112139
113140 if ($ statement === false ) {
114141 throw new RuntimeException ('Failed to prepare statement ' );
115142 }
116143
117- $ statement ->bindValue ('status ' , $ status ->value );
118- $ statement ->bindValue ('author_id ' , $ authorId );
119-
120- if ($ direction === self ::DIRECTION_BACKWARD ) {
121- $ statement ->bindValue ('cursor ' , $ beforeCursor );
122- $ statement ->bindValue ('limit ' , $ last );
123- } else {
124- if ($ afterCursor !== null ) {
125- $ statement ->bindValue ('cursor ' , $ afterCursor );
126- }
127-
128- $ statement ->bindValue ('limit ' , $ first );
144+ foreach ($ binds as $ key => $ value ) {
145+ $ statement ->bindValue ($ key , $ value );
129146 }
130147
131148 $ result = $ statement ->execute ();
0 commit comments