DatabaseQueryBuilderTest.php 229 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624
  1. <?php
  2. namespace Illuminate\Tests\Database;
  3. use BadMethodCallException;
  4. use Closure;
  5. use DateTime;
  6. use Illuminate\Database\ConnectionInterface;
  7. use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
  8. use Illuminate\Database\Query\Builder;
  9. use Illuminate\Database\Query\Expression as Raw;
  10. use Illuminate\Database\Query\Grammars\Grammar;
  11. use Illuminate\Database\Query\Grammars\MySqlGrammar;
  12. use Illuminate\Database\Query\Grammars\PostgresGrammar;
  13. use Illuminate\Database\Query\Grammars\SQLiteGrammar;
  14. use Illuminate\Database\Query\Grammars\SqlServerGrammar;
  15. use Illuminate\Database\Query\Processors\MySqlProcessor;
  16. use Illuminate\Database\Query\Processors\PostgresProcessor;
  17. use Illuminate\Database\Query\Processors\Processor;
  18. use Illuminate\Pagination\AbstractPaginator as Paginator;
  19. use Illuminate\Pagination\Cursor;
  20. use Illuminate\Pagination\CursorPaginator;
  21. use Illuminate\Pagination\LengthAwarePaginator;
  22. use InvalidArgumentException;
  23. use Mockery as m;
  24. use PHPUnit\Framework\TestCase;
  25. use RuntimeException;
  26. use stdClass;
  27. class DatabaseQueryBuilderTest extends TestCase
  28. {
  29. protected function tearDown(): void
  30. {
  31. m::close();
  32. }
  33. public function testBasicSelect()
  34. {
  35. $builder = $this->getBuilder();
  36. $builder->select('*')->from('users');
  37. $this->assertSame('select * from "users"', $builder->toSql());
  38. }
  39. public function testBasicSelectWithGetColumns()
  40. {
  41. $builder = $this->getBuilder();
  42. $builder->getProcessor()->shouldReceive('processSelect');
  43. $builder->getConnection()->shouldReceive('select')->once()->andReturnUsing(function ($sql) {
  44. $this->assertSame('select * from "users"', $sql);
  45. });
  46. $builder->getConnection()->shouldReceive('select')->once()->andReturnUsing(function ($sql) {
  47. $this->assertSame('select "foo", "bar" from "users"', $sql);
  48. });
  49. $builder->getConnection()->shouldReceive('select')->once()->andReturnUsing(function ($sql) {
  50. $this->assertSame('select "baz" from "users"', $sql);
  51. });
  52. $builder->from('users')->get();
  53. $this->assertNull($builder->columns);
  54. $builder->from('users')->get(['foo', 'bar']);
  55. $this->assertNull($builder->columns);
  56. $builder->from('users')->get('baz');
  57. $this->assertNull($builder->columns);
  58. $this->assertSame('select * from "users"', $builder->toSql());
  59. $this->assertNull($builder->columns);
  60. }
  61. public function testBasicSelectUseWritePdo()
  62. {
  63. $builder = $this->getMySqlBuilderWithProcessor();
  64. $builder->getConnection()->shouldReceive('select')->once()
  65. ->with('select * from `users`', [], false);
  66. $builder->useWritePdo()->select('*')->from('users')->get();
  67. $builder = $this->getMySqlBuilderWithProcessor();
  68. $builder->getConnection()->shouldReceive('select')->once()
  69. ->with('select * from `users`', [], true);
  70. $builder->select('*')->from('users')->get();
  71. }
  72. public function testBasicTableWrappingProtectsQuotationMarks()
  73. {
  74. $builder = $this->getBuilder();
  75. $builder->select('*')->from('some"table');
  76. $this->assertSame('select * from "some""table"', $builder->toSql());
  77. }
  78. public function testAliasWrappingAsWholeConstant()
  79. {
  80. $builder = $this->getBuilder();
  81. $builder->select('x.y as foo.bar')->from('baz');
  82. $this->assertSame('select "x"."y" as "foo.bar" from "baz"', $builder->toSql());
  83. }
  84. public function testAliasWrappingWithSpacesInDatabaseName()
  85. {
  86. $builder = $this->getBuilder();
  87. $builder->select('w x.y.z as foo.bar')->from('baz');
  88. $this->assertSame('select "w x"."y"."z" as "foo.bar" from "baz"', $builder->toSql());
  89. }
  90. public function testAddingSelects()
  91. {
  92. $builder = $this->getBuilder();
  93. $builder->select('foo')->addSelect('bar')->addSelect(['baz', 'boom'])->from('users');
  94. $this->assertSame('select "foo", "bar", "baz", "boom" from "users"', $builder->toSql());
  95. }
  96. public function testBasicSelectWithPrefix()
  97. {
  98. $builder = $this->getBuilder();
  99. $builder->getGrammar()->setTablePrefix('prefix_');
  100. $builder->select('*')->from('users');
  101. $this->assertSame('select * from "prefix_users"', $builder->toSql());
  102. }
  103. public function testBasicSelectDistinct()
  104. {
  105. $builder = $this->getBuilder();
  106. $builder->distinct()->select('foo', 'bar')->from('users');
  107. $this->assertSame('select distinct "foo", "bar" from "users"', $builder->toSql());
  108. }
  109. public function testBasicSelectDistinctOnColumns()
  110. {
  111. $builder = $this->getBuilder();
  112. $builder->distinct('foo')->select('foo', 'bar')->from('users');
  113. $this->assertSame('select distinct "foo", "bar" from "users"', $builder->toSql());
  114. $builder = $this->getPostgresBuilder();
  115. $builder->distinct('foo')->select('foo', 'bar')->from('users');
  116. $this->assertSame('select distinct on ("foo") "foo", "bar" from "users"', $builder->toSql());
  117. }
  118. public function testBasicAlias()
  119. {
  120. $builder = $this->getBuilder();
  121. $builder->select('foo as bar')->from('users');
  122. $this->assertSame('select "foo" as "bar" from "users"', $builder->toSql());
  123. }
  124. public function testAliasWithPrefix()
  125. {
  126. $builder = $this->getBuilder();
  127. $builder->getGrammar()->setTablePrefix('prefix_');
  128. $builder->select('*')->from('users as people');
  129. $this->assertSame('select * from "prefix_users" as "prefix_people"', $builder->toSql());
  130. }
  131. public function testJoinAliasesWithPrefix()
  132. {
  133. $builder = $this->getBuilder();
  134. $builder->getGrammar()->setTablePrefix('prefix_');
  135. $builder->select('*')->from('services')->join('translations AS t', 't.item_id', '=', 'services.id');
  136. $this->assertSame('select * from "prefix_services" inner join "prefix_translations" as "prefix_t" on "prefix_t"."item_id" = "prefix_services"."id"', $builder->toSql());
  137. }
  138. public function testBasicTableWrapping()
  139. {
  140. $builder = $this->getBuilder();
  141. $builder->select('*')->from('public.users');
  142. $this->assertSame('select * from "public"."users"', $builder->toSql());
  143. }
  144. public function testWhenCallback()
  145. {
  146. $callback = function ($query, $condition) {
  147. $this->assertTrue($condition);
  148. $query->where('id', '=', 1);
  149. };
  150. $builder = $this->getBuilder();
  151. $builder->select('*')->from('users')->when(true, $callback)->where('email', 'foo');
  152. $this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
  153. $builder = $this->getBuilder();
  154. $builder->select('*')->from('users')->when(false, $callback)->where('email', 'foo');
  155. $this->assertSame('select * from "users" where "email" = ?', $builder->toSql());
  156. }
  157. public function testWhenCallbackWithReturn()
  158. {
  159. $callback = function ($query, $condition) {
  160. $this->assertTrue($condition);
  161. return $query->where('id', '=', 1);
  162. };
  163. $builder = $this->getBuilder();
  164. $builder->select('*')->from('users')->when(true, $callback)->where('email', 'foo');
  165. $this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
  166. $builder = $this->getBuilder();
  167. $builder->select('*')->from('users')->when(false, $callback)->where('email', 'foo');
  168. $this->assertSame('select * from "users" where "email" = ?', $builder->toSql());
  169. }
  170. public function testWhenCallbackWithDefault()
  171. {
  172. $callback = function ($query, $condition) {
  173. $this->assertSame('truthy', $condition);
  174. $query->where('id', '=', 1);
  175. };
  176. $default = function ($query, $condition) {
  177. $this->assertEquals(0, $condition);
  178. $query->where('id', '=', 2);
  179. };
  180. $builder = $this->getBuilder();
  181. $builder->select('*')->from('users')->when('truthy', $callback, $default)->where('email', 'foo');
  182. $this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
  183. $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());
  184. $builder = $this->getBuilder();
  185. $builder->select('*')->from('users')->when(0, $callback, $default)->where('email', 'foo');
  186. $this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
  187. $this->assertEquals([0 => 2, 1 => 'foo'], $builder->getBindings());
  188. }
  189. public function testUnlessCallback()
  190. {
  191. $callback = function ($query, $condition) {
  192. $this->assertFalse($condition);
  193. $query->where('id', '=', 1);
  194. };
  195. $builder = $this->getBuilder();
  196. $builder->select('*')->from('users')->unless(false, $callback)->where('email', 'foo');
  197. $this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
  198. $builder = $this->getBuilder();
  199. $builder->select('*')->from('users')->unless(true, $callback)->where('email', 'foo');
  200. $this->assertSame('select * from "users" where "email" = ?', $builder->toSql());
  201. }
  202. public function testUnlessCallbackWithReturn()
  203. {
  204. $callback = function ($query, $condition) {
  205. $this->assertFalse($condition);
  206. return $query->where('id', '=', 1);
  207. };
  208. $builder = $this->getBuilder();
  209. $builder->select('*')->from('users')->unless(false, $callback)->where('email', 'foo');
  210. $this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
  211. $builder = $this->getBuilder();
  212. $builder->select('*')->from('users')->unless(true, $callback)->where('email', 'foo');
  213. $this->assertSame('select * from "users" where "email" = ?', $builder->toSql());
  214. }
  215. public function testUnlessCallbackWithDefault()
  216. {
  217. $callback = function ($query, $condition) {
  218. $this->assertEquals(0, $condition);
  219. $query->where('id', '=', 1);
  220. };
  221. $default = function ($query, $condition) {
  222. $this->assertSame('truthy', $condition);
  223. $query->where('id', '=', 2);
  224. };
  225. $builder = $this->getBuilder();
  226. $builder->select('*')->from('users')->unless(0, $callback, $default)->where('email', 'foo');
  227. $this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
  228. $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());
  229. $builder = $this->getBuilder();
  230. $builder->select('*')->from('users')->unless('truthy', $callback, $default)->where('email', 'foo');
  231. $this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
  232. $this->assertEquals([0 => 2, 1 => 'foo'], $builder->getBindings());
  233. }
  234. public function testTapCallback()
  235. {
  236. $callback = function ($query) {
  237. return $query->where('id', '=', 1);
  238. };
  239. $builder = $this->getBuilder();
  240. $builder->select('*')->from('users')->tap($callback)->where('email', 'foo');
  241. $this->assertSame('select * from "users" where "id" = ? and "email" = ?', $builder->toSql());
  242. }
  243. public function testBasicWheres()
  244. {
  245. $builder = $this->getBuilder();
  246. $builder->select('*')->from('users')->where('id', '=', 1);
  247. $this->assertSame('select * from "users" where "id" = ?', $builder->toSql());
  248. $this->assertEquals([0 => 1], $builder->getBindings());
  249. }
  250. public function testWheresWithArrayValue()
  251. {
  252. $builder = $this->getBuilder();
  253. $builder->select('*')->from('users')->where('id', [12]);
  254. $this->assertSame('select * from "users" where "id" = ?', $builder->toSql());
  255. $this->assertEquals([0 => 12], $builder->getBindings());
  256. $builder = $this->getBuilder();
  257. $builder->select('*')->from('users')->where('id', '=', [12, 30]);
  258. $this->assertSame('select * from "users" where "id" = ?', $builder->toSql());
  259. $this->assertEquals([0 => 12], $builder->getBindings());
  260. $builder = $this->getBuilder();
  261. $builder->select('*')->from('users')->where('id', '!=', [12, 30]);
  262. $this->assertSame('select * from "users" where "id" != ?', $builder->toSql());
  263. $this->assertEquals([0 => 12], $builder->getBindings());
  264. $builder = $this->getBuilder();
  265. $builder->select('*')->from('users')->where('id', '<>', [12, 30]);
  266. $this->assertSame('select * from "users" where "id" <> ?', $builder->toSql());
  267. $this->assertEquals([0 => 12], $builder->getBindings());
  268. $builder = $this->getBuilder();
  269. $builder->select('*')->from('users')->where('id', '=', [[12, 30]]);
  270. $this->assertSame('select * from "users" where "id" = ?', $builder->toSql());
  271. $this->assertEquals([0 => 12], $builder->getBindings());
  272. }
  273. public function testMySqlWrappingProtectsQuotationMarks()
  274. {
  275. $builder = $this->getMySqlBuilder();
  276. $builder->select('*')->From('some`table');
  277. $this->assertSame('select * from `some``table`', $builder->toSql());
  278. }
  279. public function testDateBasedWheresAcceptsTwoArguments()
  280. {
  281. $builder = $this->getMySqlBuilder();
  282. $builder->select('*')->from('users')->whereDate('created_at', 1);
  283. $this->assertSame('select * from `users` where date(`created_at`) = ?', $builder->toSql());
  284. $builder = $this->getMySqlBuilder();
  285. $builder->select('*')->from('users')->whereDay('created_at', 1);
  286. $this->assertSame('select * from `users` where day(`created_at`) = ?', $builder->toSql());
  287. $builder = $this->getMySqlBuilder();
  288. $builder->select('*')->from('users')->whereMonth('created_at', 1);
  289. $this->assertSame('select * from `users` where month(`created_at`) = ?', $builder->toSql());
  290. $builder = $this->getMySqlBuilder();
  291. $builder->select('*')->from('users')->whereYear('created_at', 1);
  292. $this->assertSame('select * from `users` where year(`created_at`) = ?', $builder->toSql());
  293. }
  294. public function testDateBasedOrWheresAcceptsTwoArguments()
  295. {
  296. $builder = $this->getMySqlBuilder();
  297. $builder->select('*')->from('users')->where('id', 1)->orWhereDate('created_at', 1);
  298. $this->assertSame('select * from `users` where `id` = ? or date(`created_at`) = ?', $builder->toSql());
  299. $builder = $this->getMySqlBuilder();
  300. $builder->select('*')->from('users')->where('id', 1)->orWhereDay('created_at', 1);
  301. $this->assertSame('select * from `users` where `id` = ? or day(`created_at`) = ?', $builder->toSql());
  302. $builder = $this->getMySqlBuilder();
  303. $builder->select('*')->from('users')->where('id', 1)->orWhereMonth('created_at', 1);
  304. $this->assertSame('select * from `users` where `id` = ? or month(`created_at`) = ?', $builder->toSql());
  305. $builder = $this->getMySqlBuilder();
  306. $builder->select('*')->from('users')->where('id', 1)->orWhereYear('created_at', 1);
  307. $this->assertSame('select * from `users` where `id` = ? or year(`created_at`) = ?', $builder->toSql());
  308. }
  309. public function testDateBasedWheresExpressionIsNotBound()
  310. {
  311. $builder = $this->getBuilder();
  312. $builder->select('*')->from('users')->whereDate('created_at', new Raw('NOW()'))->where('admin', true);
  313. $this->assertEquals([true], $builder->getBindings());
  314. $builder = $this->getBuilder();
  315. $builder->select('*')->from('users')->whereDay('created_at', new Raw('NOW()'));
  316. $this->assertEquals([], $builder->getBindings());
  317. $builder = $this->getBuilder();
  318. $builder->select('*')->from('users')->whereMonth('created_at', new Raw('NOW()'));
  319. $this->assertEquals([], $builder->getBindings());
  320. $builder = $this->getBuilder();
  321. $builder->select('*')->from('users')->whereYear('created_at', new Raw('NOW()'));
  322. $this->assertEquals([], $builder->getBindings());
  323. }
  324. public function testWhereDateMySql()
  325. {
  326. $builder = $this->getMySqlBuilder();
  327. $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-12-21');
  328. $this->assertSame('select * from `users` where date(`created_at`) = ?', $builder->toSql());
  329. $this->assertEquals([0 => '2015-12-21'], $builder->getBindings());
  330. $builder = $this->getMySqlBuilder();
  331. $builder->select('*')->from('users')->whereDate('created_at', '=', new Raw('NOW()'));
  332. $this->assertSame('select * from `users` where date(`created_at`) = NOW()', $builder->toSql());
  333. }
  334. public function testWhereDayMySql()
  335. {
  336. $builder = $this->getMySqlBuilder();
  337. $builder->select('*')->from('users')->whereDay('created_at', '=', 1);
  338. $this->assertSame('select * from `users` where day(`created_at`) = ?', $builder->toSql());
  339. $this->assertEquals([0 => 1], $builder->getBindings());
  340. }
  341. public function testOrWhereDayMySql()
  342. {
  343. $builder = $this->getMySqlBuilder();
  344. $builder->select('*')->from('users')->whereDay('created_at', '=', 1)->orWhereDay('created_at', '=', 2);
  345. $this->assertSame('select * from `users` where day(`created_at`) = ? or day(`created_at`) = ?', $builder->toSql());
  346. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  347. }
  348. public function testWhereMonthMySql()
  349. {
  350. $builder = $this->getMySqlBuilder();
  351. $builder->select('*')->from('users')->whereMonth('created_at', '=', 5);
  352. $this->assertSame('select * from `users` where month(`created_at`) = ?', $builder->toSql());
  353. $this->assertEquals([0 => 5], $builder->getBindings());
  354. }
  355. public function testOrWhereMonthMySql()
  356. {
  357. $builder = $this->getMySqlBuilder();
  358. $builder->select('*')->from('users')->whereMonth('created_at', '=', 5)->orWhereMonth('created_at', '=', 6);
  359. $this->assertSame('select * from `users` where month(`created_at`) = ? or month(`created_at`) = ?', $builder->toSql());
  360. $this->assertEquals([0 => 5, 1 => 6], $builder->getBindings());
  361. }
  362. public function testWhereYearMySql()
  363. {
  364. $builder = $this->getMySqlBuilder();
  365. $builder->select('*')->from('users')->whereYear('created_at', '=', 2014);
  366. $this->assertSame('select * from `users` where year(`created_at`) = ?', $builder->toSql());
  367. $this->assertEquals([0 => 2014], $builder->getBindings());
  368. }
  369. public function testOrWhereYearMySql()
  370. {
  371. $builder = $this->getMySqlBuilder();
  372. $builder->select('*')->from('users')->whereYear('created_at', '=', 2014)->orWhereYear('created_at', '=', 2015);
  373. $this->assertSame('select * from `users` where year(`created_at`) = ? or year(`created_at`) = ?', $builder->toSql());
  374. $this->assertEquals([0 => 2014, 1 => 2015], $builder->getBindings());
  375. }
  376. public function testWhereTimeMySql()
  377. {
  378. $builder = $this->getMySqlBuilder();
  379. $builder->select('*')->from('users')->whereTime('created_at', '>=', '22:00');
  380. $this->assertSame('select * from `users` where time(`created_at`) >= ?', $builder->toSql());
  381. $this->assertEquals([0 => '22:00'], $builder->getBindings());
  382. }
  383. public function testWhereTimeOperatorOptionalMySql()
  384. {
  385. $builder = $this->getMySqlBuilder();
  386. $builder->select('*')->from('users')->whereTime('created_at', '22:00');
  387. $this->assertSame('select * from `users` where time(`created_at`) = ?', $builder->toSql());
  388. $this->assertEquals([0 => '22:00'], $builder->getBindings());
  389. }
  390. public function testWhereTimeOperatorOptionalPostgres()
  391. {
  392. $builder = $this->getPostgresBuilder();
  393. $builder->select('*')->from('users')->whereTime('created_at', '22:00');
  394. $this->assertSame('select * from "users" where "created_at"::time = ?', $builder->toSql());
  395. $this->assertEquals([0 => '22:00'], $builder->getBindings());
  396. }
  397. public function testWhereTimeSqlServer()
  398. {
  399. $builder = $this->getSqlServerBuilder();
  400. $builder->select('*')->from('users')->whereTime('created_at', '22:00');
  401. $this->assertSame('select * from [users] where cast([created_at] as time) = ?', $builder->toSql());
  402. $this->assertEquals([0 => '22:00'], $builder->getBindings());
  403. $builder = $this->getSqlServerBuilder();
  404. $builder->select('*')->from('users')->whereTime('created_at', new Raw('NOW()'));
  405. $this->assertSame('select * from [users] where cast([created_at] as time) = NOW()', $builder->toSql());
  406. $this->assertEquals([], $builder->getBindings());
  407. }
  408. public function testWhereDatePostgres()
  409. {
  410. $builder = $this->getPostgresBuilder();
  411. $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-12-21');
  412. $this->assertSame('select * from "users" where "created_at"::date = ?', $builder->toSql());
  413. $this->assertEquals([0 => '2015-12-21'], $builder->getBindings());
  414. $builder = $this->getPostgresBuilder();
  415. $builder->select('*')->from('users')->whereDate('created_at', new Raw('NOW()'));
  416. $this->assertSame('select * from "users" where "created_at"::date = NOW()', $builder->toSql());
  417. }
  418. public function testWhereDayPostgres()
  419. {
  420. $builder = $this->getPostgresBuilder();
  421. $builder->select('*')->from('users')->whereDay('created_at', '=', 1);
  422. $this->assertSame('select * from "users" where extract(day from "created_at") = ?', $builder->toSql());
  423. $this->assertEquals([0 => 1], $builder->getBindings());
  424. }
  425. public function testWhereMonthPostgres()
  426. {
  427. $builder = $this->getPostgresBuilder();
  428. $builder->select('*')->from('users')->whereMonth('created_at', '=', 5);
  429. $this->assertSame('select * from "users" where extract(month from "created_at") = ?', $builder->toSql());
  430. $this->assertEquals([0 => 5], $builder->getBindings());
  431. }
  432. public function testWhereYearPostgres()
  433. {
  434. $builder = $this->getPostgresBuilder();
  435. $builder->select('*')->from('users')->whereYear('created_at', '=', 2014);
  436. $this->assertSame('select * from "users" where extract(year from "created_at") = ?', $builder->toSql());
  437. $this->assertEquals([0 => 2014], $builder->getBindings());
  438. }
  439. public function testWhereTimePostgres()
  440. {
  441. $builder = $this->getPostgresBuilder();
  442. $builder->select('*')->from('users')->whereTime('created_at', '>=', '22:00');
  443. $this->assertSame('select * from "users" where "created_at"::time >= ?', $builder->toSql());
  444. $this->assertEquals([0 => '22:00'], $builder->getBindings());
  445. }
  446. public function testWhereLikePostgres()
  447. {
  448. $builder = $this->getPostgresBuilder();
  449. $builder->select('*')->from('users')->where('id', 'like', '1');
  450. $this->assertSame('select * from "users" where "id"::text like ?', $builder->toSql());
  451. $this->assertEquals([0 => '1'], $builder->getBindings());
  452. $builder = $this->getPostgresBuilder();
  453. $builder->select('*')->from('users')->where('id', 'LIKE', '1');
  454. $this->assertSame('select * from "users" where "id"::text LIKE ?', $builder->toSql());
  455. $this->assertEquals([0 => '1'], $builder->getBindings());
  456. $builder = $this->getPostgresBuilder();
  457. $builder->select('*')->from('users')->where('id', 'ilike', '1');
  458. $this->assertSame('select * from "users" where "id"::text ilike ?', $builder->toSql());
  459. $this->assertEquals([0 => '1'], $builder->getBindings());
  460. $builder = $this->getPostgresBuilder();
  461. $builder->select('*')->from('users')->where('id', 'not like', '1');
  462. $this->assertSame('select * from "users" where "id"::text not like ?', $builder->toSql());
  463. $this->assertEquals([0 => '1'], $builder->getBindings());
  464. $builder = $this->getPostgresBuilder();
  465. $builder->select('*')->from('users')->where('id', 'not ilike', '1');
  466. $this->assertSame('select * from "users" where "id"::text not ilike ?', $builder->toSql());
  467. $this->assertEquals([0 => '1'], $builder->getBindings());
  468. }
  469. public function testWhereDateSqlite()
  470. {
  471. $builder = $this->getSQLiteBuilder();
  472. $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-12-21');
  473. $this->assertSame('select * from "users" where strftime(\'%Y-%m-%d\', "created_at") = cast(? as text)', $builder->toSql());
  474. $this->assertEquals([0 => '2015-12-21'], $builder->getBindings());
  475. $builder = $this->getSQLiteBuilder();
  476. $builder->select('*')->from('users')->whereDate('created_at', new Raw('NOW()'));
  477. $this->assertSame('select * from "users" where strftime(\'%Y-%m-%d\', "created_at") = cast(NOW() as text)', $builder->toSql());
  478. }
  479. public function testWhereDaySqlite()
  480. {
  481. $builder = $this->getSQLiteBuilder();
  482. $builder->select('*')->from('users')->whereDay('created_at', '=', 1);
  483. $this->assertSame('select * from "users" where strftime(\'%d\', "created_at") = cast(? as text)', $builder->toSql());
  484. $this->assertEquals([0 => 1], $builder->getBindings());
  485. }
  486. public function testWhereMonthSqlite()
  487. {
  488. $builder = $this->getSQLiteBuilder();
  489. $builder->select('*')->from('users')->whereMonth('created_at', '=', 5);
  490. $this->assertSame('select * from "users" where strftime(\'%m\', "created_at") = cast(? as text)', $builder->toSql());
  491. $this->assertEquals([0 => 5], $builder->getBindings());
  492. }
  493. public function testWhereYearSqlite()
  494. {
  495. $builder = $this->getSQLiteBuilder();
  496. $builder->select('*')->from('users')->whereYear('created_at', '=', 2014);
  497. $this->assertSame('select * from "users" where strftime(\'%Y\', "created_at") = cast(? as text)', $builder->toSql());
  498. $this->assertEquals([0 => 2014], $builder->getBindings());
  499. }
  500. public function testWhereTimeSqlite()
  501. {
  502. $builder = $this->getSQLiteBuilder();
  503. $builder->select('*')->from('users')->whereTime('created_at', '>=', '22:00');
  504. $this->assertSame('select * from "users" where strftime(\'%H:%M:%S\', "created_at") >= cast(? as text)', $builder->toSql());
  505. $this->assertEquals([0 => '22:00'], $builder->getBindings());
  506. }
  507. public function testWhereTimeOperatorOptionalSqlite()
  508. {
  509. $builder = $this->getSQLiteBuilder();
  510. $builder->select('*')->from('users')->whereTime('created_at', '22:00');
  511. $this->assertSame('select * from "users" where strftime(\'%H:%M:%S\', "created_at") = cast(? as text)', $builder->toSql());
  512. $this->assertEquals([0 => '22:00'], $builder->getBindings());
  513. }
  514. public function testWhereDateSqlServer()
  515. {
  516. $builder = $this->getSqlServerBuilder();
  517. $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-12-21');
  518. $this->assertSame('select * from [users] where cast([created_at] as date) = ?', $builder->toSql());
  519. $this->assertEquals([0 => '2015-12-21'], $builder->getBindings());
  520. $builder = $this->getSqlServerBuilder();
  521. $builder->select('*')->from('users')->whereDate('created_at', new Raw('NOW()'));
  522. $this->assertSame('select * from [users] where cast([created_at] as date) = NOW()', $builder->toSql());
  523. }
  524. public function testWhereDaySqlServer()
  525. {
  526. $builder = $this->getSqlServerBuilder();
  527. $builder->select('*')->from('users')->whereDay('created_at', '=', 1);
  528. $this->assertSame('select * from [users] where day([created_at]) = ?', $builder->toSql());
  529. $this->assertEquals([0 => 1], $builder->getBindings());
  530. }
  531. public function testWhereMonthSqlServer()
  532. {
  533. $builder = $this->getSqlServerBuilder();
  534. $builder->select('*')->from('users')->whereMonth('created_at', '=', 5);
  535. $this->assertSame('select * from [users] where month([created_at]) = ?', $builder->toSql());
  536. $this->assertEquals([0 => 5], $builder->getBindings());
  537. }
  538. public function testWhereYearSqlServer()
  539. {
  540. $builder = $this->getSqlServerBuilder();
  541. $builder->select('*')->from('users')->whereYear('created_at', '=', 2014);
  542. $this->assertSame('select * from [users] where year([created_at]) = ?', $builder->toSql());
  543. $this->assertEquals([0 => 2014], $builder->getBindings());
  544. }
  545. public function testWhereBetweens()
  546. {
  547. $builder = $this->getBuilder();
  548. $builder->select('*')->from('users')->whereBetween('id', [1, 2]);
  549. $this->assertSame('select * from "users" where "id" between ? and ?', $builder->toSql());
  550. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  551. $builder = $this->getBuilder();
  552. $builder->select('*')->from('users')->whereBetween('id', [[1, 2, 3]]);
  553. $this->assertSame('select * from "users" where "id" between ? and ?', $builder->toSql());
  554. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  555. $builder = $this->getBuilder();
  556. $builder->select('*')->from('users')->whereBetween('id', [[1], [2, 3]]);
  557. $this->assertSame('select * from "users" where "id" between ? and ?', $builder->toSql());
  558. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  559. $builder = $this->getBuilder();
  560. $builder->select('*')->from('users')->whereNotBetween('id', [1, 2]);
  561. $this->assertSame('select * from "users" where "id" not between ? and ?', $builder->toSql());
  562. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  563. $builder = $this->getBuilder();
  564. $builder->select('*')->from('users')->whereBetween('id', [new Raw(1), new Raw(2)]);
  565. $this->assertSame('select * from "users" where "id" between 1 and 2', $builder->toSql());
  566. $this->assertEquals([], $builder->getBindings());
  567. }
  568. public function testWhereBetweenColumns()
  569. {
  570. $builder = $this->getBuilder();
  571. $builder->select('*')->from('users')->whereBetweenColumns('id', ['users.created_at', 'users.updated_at']);
  572. $this->assertSame('select * from "users" where "id" between "users"."created_at" and "users"."updated_at"', $builder->toSql());
  573. $this->assertEquals([], $builder->getBindings());
  574. $builder = $this->getBuilder();
  575. $builder->select('*')->from('users')->whereNotBetweenColumns('id', ['created_at', 'updated_at']);
  576. $this->assertSame('select * from "users" where "id" not between "created_at" and "updated_at"', $builder->toSql());
  577. $this->assertEquals([], $builder->getBindings());
  578. $builder = $this->getBuilder();
  579. $builder->select('*')->from('users')->whereBetweenColumns('id', [new Raw(1), new Raw(2)]);
  580. $this->assertSame('select * from "users" where "id" between 1 and 2', $builder->toSql());
  581. $this->assertEquals([], $builder->getBindings());
  582. }
  583. public function testBasicOrWheres()
  584. {
  585. $builder = $this->getBuilder();
  586. $builder->select('*')->from('users')->where('id', '=', 1)->orWhere('email', '=', 'foo');
  587. $this->assertSame('select * from "users" where "id" = ? or "email" = ?', $builder->toSql());
  588. $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());
  589. }
  590. public function testRawWheres()
  591. {
  592. $builder = $this->getBuilder();
  593. $builder->select('*')->from('users')->whereRaw('id = ? or email = ?', [1, 'foo']);
  594. $this->assertSame('select * from "users" where id = ? or email = ?', $builder->toSql());
  595. $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());
  596. }
  597. public function testRawOrWheres()
  598. {
  599. $builder = $this->getBuilder();
  600. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereRaw('email = ?', ['foo']);
  601. $this->assertSame('select * from "users" where "id" = ? or email = ?', $builder->toSql());
  602. $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());
  603. }
  604. public function testBasicWhereIns()
  605. {
  606. $builder = $this->getBuilder();
  607. $builder->select('*')->from('users')->whereIn('id', [1, 2, 3]);
  608. $this->assertSame('select * from "users" where "id" in (?, ?, ?)', $builder->toSql());
  609. $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings());
  610. $builder = $this->getBuilder();
  611. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIn('id', [1, 2, 3]);
  612. $this->assertSame('select * from "users" where "id" = ? or "id" in (?, ?, ?)', $builder->toSql());
  613. $this->assertEquals([0 => 1, 1 => 1, 2 => 2, 3 => 3], $builder->getBindings());
  614. }
  615. public function testBasicWhereNotIns()
  616. {
  617. $builder = $this->getBuilder();
  618. $builder->select('*')->from('users')->whereNotIn('id', [1, 2, 3]);
  619. $this->assertSame('select * from "users" where "id" not in (?, ?, ?)', $builder->toSql());
  620. $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings());
  621. $builder = $this->getBuilder();
  622. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotIn('id', [1, 2, 3]);
  623. $this->assertSame('select * from "users" where "id" = ? or "id" not in (?, ?, ?)', $builder->toSql());
  624. $this->assertEquals([0 => 1, 1 => 1, 2 => 2, 3 => 3], $builder->getBindings());
  625. }
  626. public function testRawWhereIns()
  627. {
  628. $builder = $this->getBuilder();
  629. $builder->select('*')->from('users')->whereIn('id', [new Raw(1)]);
  630. $this->assertSame('select * from "users" where "id" in (1)', $builder->toSql());
  631. $builder = $this->getBuilder();
  632. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIn('id', [new Raw(1)]);
  633. $this->assertSame('select * from "users" where "id" = ? or "id" in (1)', $builder->toSql());
  634. $this->assertEquals([0 => 1], $builder->getBindings());
  635. }
  636. public function testEmptyWhereIns()
  637. {
  638. $builder = $this->getBuilder();
  639. $builder->select('*')->from('users')->whereIn('id', []);
  640. $this->assertSame('select * from "users" where 0 = 1', $builder->toSql());
  641. $this->assertEquals([], $builder->getBindings());
  642. $builder = $this->getBuilder();
  643. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIn('id', []);
  644. $this->assertSame('select * from "users" where "id" = ? or 0 = 1', $builder->toSql());
  645. $this->assertEquals([0 => 1], $builder->getBindings());
  646. }
  647. public function testEmptyWhereNotIns()
  648. {
  649. $builder = $this->getBuilder();
  650. $builder->select('*')->from('users')->whereNotIn('id', []);
  651. $this->assertSame('select * from "users" where 1 = 1', $builder->toSql());
  652. $this->assertEquals([], $builder->getBindings());
  653. $builder = $this->getBuilder();
  654. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNotIn('id', []);
  655. $this->assertSame('select * from "users" where "id" = ? or 1 = 1', $builder->toSql());
  656. $this->assertEquals([0 => 1], $builder->getBindings());
  657. }
  658. public function testWhereIntegerInRaw()
  659. {
  660. $builder = $this->getBuilder();
  661. $builder->select('*')->from('users')->whereIntegerInRaw('id', ['1a', 2]);
  662. $this->assertSame('select * from "users" where "id" in (1, 2)', $builder->toSql());
  663. $this->assertEquals([], $builder->getBindings());
  664. }
  665. public function testOrWhereIntegerInRaw()
  666. {
  667. $builder = $this->getBuilder();
  668. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIntegerInRaw('id', ['1a', 2]);
  669. $this->assertSame('select * from "users" where "id" = ? or "id" in (1, 2)', $builder->toSql());
  670. $this->assertEquals([0 => 1], $builder->getBindings());
  671. }
  672. public function testWhereIntegerNotInRaw()
  673. {
  674. $builder = $this->getBuilder();
  675. $builder->select('*')->from('users')->whereIntegerNotInRaw('id', ['1a', 2]);
  676. $this->assertSame('select * from "users" where "id" not in (1, 2)', $builder->toSql());
  677. $this->assertEquals([], $builder->getBindings());
  678. }
  679. public function testOrWhereIntegerNotInRaw()
  680. {
  681. $builder = $this->getBuilder();
  682. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIntegerNotInRaw('id', ['1a', 2]);
  683. $this->assertSame('select * from "users" where "id" = ? or "id" not in (1, 2)', $builder->toSql());
  684. $this->assertEquals([0 => 1], $builder->getBindings());
  685. }
  686. public function testEmptyWhereIntegerInRaw()
  687. {
  688. $builder = $this->getBuilder();
  689. $builder->select('*')->from('users')->whereIntegerInRaw('id', []);
  690. $this->assertSame('select * from "users" where 0 = 1', $builder->toSql());
  691. $this->assertEquals([], $builder->getBindings());
  692. }
  693. public function testEmptyWhereIntegerNotInRaw()
  694. {
  695. $builder = $this->getBuilder();
  696. $builder->select('*')->from('users')->whereIntegerNotInRaw('id', []);
  697. $this->assertSame('select * from "users" where 1 = 1', $builder->toSql());
  698. $this->assertEquals([], $builder->getBindings());
  699. }
  700. public function testBasicWhereColumn()
  701. {
  702. $builder = $this->getBuilder();
  703. $builder->select('*')->from('users')->whereColumn('first_name', 'last_name')->orWhereColumn('first_name', 'middle_name');
  704. $this->assertSame('select * from "users" where "first_name" = "last_name" or "first_name" = "middle_name"', $builder->toSql());
  705. $this->assertEquals([], $builder->getBindings());
  706. $builder = $this->getBuilder();
  707. $builder->select('*')->from('users')->whereColumn('updated_at', '>', 'created_at');
  708. $this->assertSame('select * from "users" where "updated_at" > "created_at"', $builder->toSql());
  709. $this->assertEquals([], $builder->getBindings());
  710. }
  711. public function testArrayWhereColumn()
  712. {
  713. $conditions = [
  714. ['first_name', 'last_name'],
  715. ['updated_at', '>', 'created_at'],
  716. ];
  717. $builder = $this->getBuilder();
  718. $builder->select('*')->from('users')->whereColumn($conditions);
  719. $this->assertSame('select * from "users" where ("first_name" = "last_name" and "updated_at" > "created_at")', $builder->toSql());
  720. $this->assertEquals([], $builder->getBindings());
  721. }
  722. public function testWhereFulltextMySql()
  723. {
  724. $builder = $this->getMySqlBuilderWithProcessor();
  725. $builder->select('*')->from('users')->whereFulltext('body', 'Hello World');
  726. $this->assertSame('select * from `users` where match (`body`) against (? in natural language mode)', $builder->toSql());
  727. $this->assertEquals(['Hello World'], $builder->getBindings());
  728. $builder = $this->getMySqlBuilderWithProcessor();
  729. $builder->select('*')->from('users')->whereFulltext('body', 'Hello World', ['expanded' => true]);
  730. $this->assertSame('select * from `users` where match (`body`) against (? in natural language mode with query expansion)', $builder->toSql());
  731. $this->assertEquals(['Hello World'], $builder->getBindings());
  732. $builder = $this->getMySqlBuilderWithProcessor();
  733. $builder->select('*')->from('users')->whereFulltext('body', '+Hello -World', ['mode' => 'boolean']);
  734. $this->assertSame('select * from `users` where match (`body`) against (? in boolean mode)', $builder->toSql());
  735. $this->assertEquals(['+Hello -World'], $builder->getBindings());
  736. $builder = $this->getMySqlBuilderWithProcessor();
  737. $builder->select('*')->from('users')->whereFulltext('body', '+Hello -World', ['mode' => 'boolean', 'expanded' => true]);
  738. $this->assertSame('select * from `users` where match (`body`) against (? in boolean mode)', $builder->toSql());
  739. $this->assertEquals(['+Hello -World'], $builder->getBindings());
  740. $builder = $this->getMySqlBuilderWithProcessor();
  741. $builder->select('*')->from('users')->whereFulltext(['body', 'title'], 'Car,Plane');
  742. $this->assertSame('select * from `users` where match (`body`, `title`) against (? in natural language mode)', $builder->toSql());
  743. $this->assertEquals(['Car,Plane'], $builder->getBindings());
  744. }
  745. public function testWhereFulltextPostgres()
  746. {
  747. $builder = $this->getPostgresBuilderWithProcessor();
  748. $builder->select('*')->from('users')->whereFulltext('body', 'Hello World');
  749. $this->assertSame('select * from "users" where (to_tsvector(\'english\', "body")) @@ plainto_tsquery(\'english\', ?)', $builder->toSql());
  750. $this->assertEquals(['Hello World'], $builder->getBindings());
  751. $builder = $this->getPostgresBuilderWithProcessor();
  752. $builder->select('*')->from('users')->whereFulltext('body', 'Hello World', ['language' => 'simple']);
  753. $this->assertSame('select * from "users" where (to_tsvector(\'simple\', "body")) @@ plainto_tsquery(\'simple\', ?)', $builder->toSql());
  754. $this->assertEquals(['Hello World'], $builder->getBindings());
  755. $builder = $this->getPostgresBuilderWithProcessor();
  756. $builder->select('*')->from('users')->whereFulltext('body', 'Hello World', ['mode' => 'plain']);
  757. $this->assertSame('select * from "users" where (to_tsvector(\'english\', "body")) @@ plainto_tsquery(\'english\', ?)', $builder->toSql());
  758. $this->assertEquals(['Hello World'], $builder->getBindings());
  759. $builder = $this->getPostgresBuilderWithProcessor();
  760. $builder->select('*')->from('users')->whereFulltext('body', 'Hello World', ['mode' => 'phrase']);
  761. $this->assertSame('select * from "users" where (to_tsvector(\'english\', "body")) @@ phraseto_tsquery(\'english\', ?)', $builder->toSql());
  762. $this->assertEquals(['Hello World'], $builder->getBindings());
  763. $builder = $this->getPostgresBuilderWithProcessor();
  764. $builder->select('*')->from('users')->whereFulltext('body', '+Hello -World', ['mode' => 'websearch']);
  765. $this->assertSame('select * from "users" where (to_tsvector(\'english\', "body")) @@ websearch_to_tsquery(\'english\', ?)', $builder->toSql());
  766. $this->assertEquals(['+Hello -World'], $builder->getBindings());
  767. $builder = $this->getPostgresBuilderWithProcessor();
  768. $builder->select('*')->from('users')->whereFulltext('body', 'Hello World', ['language' => 'simple', 'mode' => 'plain']);
  769. $this->assertSame('select * from "users" where (to_tsvector(\'simple\', "body")) @@ plainto_tsquery(\'simple\', ?)', $builder->toSql());
  770. $this->assertEquals(['Hello World'], $builder->getBindings());
  771. $builder = $this->getPostgresBuilderWithProcessor();
  772. $builder->select('*')->from('users')->whereFulltext(['body', 'title'], 'Car Plane');
  773. $this->assertSame('select * from "users" where (to_tsvector(\'english\', "body") || to_tsvector(\'english\', "title")) @@ plainto_tsquery(\'english\', ?)', $builder->toSql());
  774. $this->assertEquals(['Car Plane'], $builder->getBindings());
  775. }
  776. public function testUnions()
  777. {
  778. $builder = $this->getBuilder();
  779. $builder->select('*')->from('users')->where('id', '=', 1);
  780. $builder->union($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));
  781. $this->assertSame('(select * from "users" where "id" = ?) union (select * from "users" where "id" = ?)', $builder->toSql());
  782. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  783. $builder = $this->getMySqlBuilder();
  784. $builder->select('*')->from('users')->where('id', '=', 1);
  785. $builder->union($this->getMySqlBuilder()->select('*')->from('users')->where('id', '=', 2));
  786. $this->assertSame('(select * from `users` where `id` = ?) union (select * from `users` where `id` = ?)', $builder->toSql());
  787. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  788. $builder = $this->getMysqlBuilder();
  789. $expectedSql = '(select `a` from `t1` where `a` = ? and `b` = ?) union (select `a` from `t2` where `a` = ? and `b` = ?) order by `a` asc limit 10';
  790. $union = $this->getMysqlBuilder()->select('a')->from('t2')->where('a', 11)->where('b', 2);
  791. $builder->select('a')->from('t1')->where('a', 10)->where('b', 1)->union($union)->orderBy('a')->limit(10);
  792. $this->assertEquals($expectedSql, $builder->toSql());
  793. $this->assertEquals([0 => 10, 1 => 1, 2 => 11, 3 => 2], $builder->getBindings());
  794. $builder = $this->getPostgresBuilder();
  795. $expectedSql = '(select "name" from "users" where "id" = ?) union (select "name" from "users" where "id" = ?)';
  796. $builder->select('name')->from('users')->where('id', '=', 1);
  797. $builder->union($this->getPostgresBuilder()->select('name')->from('users')->where('id', '=', 2));
  798. $this->assertEquals($expectedSql, $builder->toSql());
  799. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  800. $builder = $this->getSQLiteBuilder();
  801. $expectedSql = 'select * from (select "name" from "users" where "id" = ?) union select * from (select "name" from "users" where "id" = ?)';
  802. $builder->select('name')->from('users')->where('id', '=', 1);
  803. $builder->union($this->getSQLiteBuilder()->select('name')->from('users')->where('id', '=', 2));
  804. $this->assertEquals($expectedSql, $builder->toSql());
  805. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  806. $builder = $this->getSqlServerBuilder();
  807. $expectedSql = 'select * from (select [name] from [users] where [id] = ?) as [temp_table] union select * from (select [name] from [users] where [id] = ?) as [temp_table]';
  808. $builder->select('name')->from('users')->where('id', '=', 1);
  809. $builder->union($this->getSqlServerBuilder()->select('name')->from('users')->where('id', '=', 2));
  810. $this->assertEquals($expectedSql, $builder->toSql());
  811. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  812. }
  813. public function testUnionAlls()
  814. {
  815. $builder = $this->getBuilder();
  816. $builder->select('*')->from('users')->where('id', '=', 1);
  817. $builder->unionAll($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));
  818. $this->assertSame('(select * from "users" where "id" = ?) union all (select * from "users" where "id" = ?)', $builder->toSql());
  819. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  820. $expectedSql = '(select * from "users" where "id" = ?) union all (select * from "users" where "id" = ?)';
  821. $builder = $this->getPostgresBuilder();
  822. $builder->select('*')->from('users')->where('id', '=', 1);
  823. $builder->unionAll($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));
  824. $this->assertEquals($expectedSql, $builder->toSql());
  825. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  826. }
  827. public function testMultipleUnions()
  828. {
  829. $builder = $this->getBuilder();
  830. $builder->select('*')->from('users')->where('id', '=', 1);
  831. $builder->union($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));
  832. $builder->union($this->getBuilder()->select('*')->from('users')->where('id', '=', 3));
  833. $this->assertSame('(select * from "users" where "id" = ?) union (select * from "users" where "id" = ?) union (select * from "users" where "id" = ?)', $builder->toSql());
  834. $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings());
  835. }
  836. public function testMultipleUnionAlls()
  837. {
  838. $builder = $this->getBuilder();
  839. $builder->select('*')->from('users')->where('id', '=', 1);
  840. $builder->unionAll($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));
  841. $builder->unionAll($this->getBuilder()->select('*')->from('users')->where('id', '=', 3));
  842. $this->assertSame('(select * from "users" where "id" = ?) union all (select * from "users" where "id" = ?) union all (select * from "users" where "id" = ?)', $builder->toSql());
  843. $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings());
  844. }
  845. public function testUnionOrderBys()
  846. {
  847. $builder = $this->getBuilder();
  848. $builder->select('*')->from('users')->where('id', '=', 1);
  849. $builder->union($this->getBuilder()->select('*')->from('users')->where('id', '=', 2));
  850. $builder->orderBy('id', 'desc');
  851. $this->assertSame('(select * from "users" where "id" = ?) union (select * from "users" where "id" = ?) order by "id" desc', $builder->toSql());
  852. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  853. }
  854. public function testUnionLimitsAndOffsets()
  855. {
  856. $builder = $this->getBuilder();
  857. $builder->select('*')->from('users');
  858. $builder->union($this->getBuilder()->select('*')->from('dogs'));
  859. $builder->skip(5)->take(10);
  860. $this->assertSame('(select * from "users") union (select * from "dogs") limit 10 offset 5', $builder->toSql());
  861. $expectedSql = '(select * from "users") union (select * from "dogs") limit 10 offset 5';
  862. $builder = $this->getPostgresBuilder();
  863. $builder->select('*')->from('users');
  864. $builder->union($this->getBuilder()->select('*')->from('dogs'));
  865. $builder->skip(5)->take(10);
  866. $this->assertEquals($expectedSql, $builder->toSql());
  867. $expectedSql = '(select * from "users" limit 11) union (select * from "dogs" limit 22) limit 10 offset 5';
  868. $builder = $this->getPostgresBuilder();
  869. $builder->select('*')->from('users')->limit(11);
  870. $builder->union($this->getBuilder()->select('*')->from('dogs')->limit(22));
  871. $builder->skip(5)->take(10);
  872. $this->assertEquals($expectedSql, $builder->toSql());
  873. }
  874. public function testUnionWithJoin()
  875. {
  876. $builder = $this->getBuilder();
  877. $builder->select('*')->from('users');
  878. $builder->union($this->getBuilder()->select('*')->from('dogs')->join('breeds', function ($join) {
  879. $join->on('dogs.breed_id', '=', 'breeds.id')
  880. ->where('breeds.is_native', '=', 1);
  881. }));
  882. $this->assertSame('(select * from "users") union (select * from "dogs" inner join "breeds" on "dogs"."breed_id" = "breeds"."id" and "breeds"."is_native" = ?)', $builder->toSql());
  883. $this->assertEquals([0 => 1], $builder->getBindings());
  884. }
  885. public function testMySqlUnionOrderBys()
  886. {
  887. $builder = $this->getMySqlBuilder();
  888. $builder->select('*')->from('users')->where('id', '=', 1);
  889. $builder->union($this->getMySqlBuilder()->select('*')->from('users')->where('id', '=', 2));
  890. $builder->orderBy('id', 'desc');
  891. $this->assertSame('(select * from `users` where `id` = ?) union (select * from `users` where `id` = ?) order by `id` desc', $builder->toSql());
  892. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  893. }
  894. public function testMySqlUnionLimitsAndOffsets()
  895. {
  896. $builder = $this->getMySqlBuilder();
  897. $builder->select('*')->from('users');
  898. $builder->union($this->getMySqlBuilder()->select('*')->from('dogs'));
  899. $builder->skip(5)->take(10);
  900. $this->assertSame('(select * from `users`) union (select * from `dogs`) limit 10 offset 5', $builder->toSql());
  901. }
  902. public function testUnionAggregate()
  903. {
  904. $expected = 'select count(*) as aggregate from ((select * from `posts`) union (select * from `videos`)) as `temp_table`';
  905. $builder = $this->getMySqlBuilder();
  906. $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true);
  907. $builder->getProcessor()->shouldReceive('processSelect')->once();
  908. $builder->from('posts')->union($this->getMySqlBuilder()->from('videos'))->count();
  909. $expected = 'select count(*) as aggregate from ((select `id` from `posts`) union (select `id` from `videos`)) as `temp_table`';
  910. $builder = $this->getMySqlBuilder();
  911. $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true);
  912. $builder->getProcessor()->shouldReceive('processSelect')->once();
  913. $builder->from('posts')->select('id')->union($this->getMySqlBuilder()->from('videos')->select('id'))->count();
  914. $expected = 'select count(*) as aggregate from ((select * from "posts") union (select * from "videos")) as "temp_table"';
  915. $builder = $this->getPostgresBuilder();
  916. $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true);
  917. $builder->getProcessor()->shouldReceive('processSelect')->once();
  918. $builder->from('posts')->union($this->getPostgresBuilder()->from('videos'))->count();
  919. $expected = 'select count(*) as aggregate from (select * from (select * from "posts") union select * from (select * from "videos")) as "temp_table"';
  920. $builder = $this->getSQLiteBuilder();
  921. $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true);
  922. $builder->getProcessor()->shouldReceive('processSelect')->once();
  923. $builder->from('posts')->union($this->getSQLiteBuilder()->from('videos'))->count();
  924. $expected = 'select count(*) as aggregate from (select * from (select * from [posts]) as [temp_table] union select * from (select * from [videos]) as [temp_table]) as [temp_table]';
  925. $builder = $this->getSqlServerBuilder();
  926. $builder->getConnection()->shouldReceive('select')->once()->with($expected, [], true);
  927. $builder->getProcessor()->shouldReceive('processSelect')->once();
  928. $builder->from('posts')->union($this->getSqlServerBuilder()->from('videos'))->count();
  929. }
  930. public function testHavingAggregate()
  931. {
  932. $expected = 'select count(*) as aggregate from (select (select `count(*)` from `videos` where `posts`.`id` = `videos`.`post_id`) as `videos_count` from `posts` having `videos_count` > ?) as `temp_table`';
  933. $builder = $this->getMySqlBuilder();
  934. $builder->getConnection()->shouldReceive('getDatabaseName');
  935. $builder->getConnection()->shouldReceive('select')->once()->with($expected, [0 => 1], true)->andReturn([['aggregate' => 1]]);
  936. $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {
  937. return $results;
  938. });
  939. $builder->from('posts')->selectSub(function ($query) {
  940. $query->from('videos')->select('count(*)')->whereColumn('posts.id', '=', 'videos.post_id');
  941. }, 'videos_count')->having('videos_count', '>', 1);
  942. $builder->count();
  943. }
  944. public function testSubSelectWhereIns()
  945. {
  946. $builder = $this->getBuilder();
  947. $builder->select('*')->from('users')->whereIn('id', function ($q) {
  948. $q->select('id')->from('users')->where('age', '>', 25)->take(3);
  949. });
  950. $this->assertSame('select * from "users" where "id" in (select "id" from "users" where "age" > ? limit 3)', $builder->toSql());
  951. $this->assertEquals([25], $builder->getBindings());
  952. $builder = $this->getBuilder();
  953. $builder->select('*')->from('users')->whereNotIn('id', function ($q) {
  954. $q->select('id')->from('users')->where('age', '>', 25)->take(3);
  955. });
  956. $this->assertSame('select * from "users" where "id" not in (select "id" from "users" where "age" > ? limit 3)', $builder->toSql());
  957. $this->assertEquals([25], $builder->getBindings());
  958. }
  959. public function testBasicWhereNulls()
  960. {
  961. $builder = $this->getBuilder();
  962. $builder->select('*')->from('users')->whereNull('id');
  963. $this->assertSame('select * from "users" where "id" is null', $builder->toSql());
  964. $this->assertEquals([], $builder->getBindings());
  965. $builder = $this->getBuilder();
  966. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNull('id');
  967. $this->assertSame('select * from "users" where "id" = ? or "id" is null', $builder->toSql());
  968. $this->assertEquals([0 => 1], $builder->getBindings());
  969. }
  970. public function testJsonWhereNullMysql()
  971. {
  972. $builder = $this->getMySqlBuilder();
  973. $builder->select('*')->from('users')->whereNull('items->id');
  974. $this->assertSame('select * from `users` where (json_extract(`items`, \'$."id"\') is null OR json_type(json_extract(`items`, \'$."id"\')) = \'NULL\')', $builder->toSql());
  975. }
  976. public function testJsonWhereNotNullMysql()
  977. {
  978. $builder = $this->getMySqlBuilder();
  979. $builder->select('*')->from('users')->whereNotNull('items->id');
  980. $this->assertSame('select * from `users` where (json_extract(`items`, \'$."id"\') is not null AND json_type(json_extract(`items`, \'$."id"\')) != \'NULL\')', $builder->toSql());
  981. }
  982. public function testArrayWhereNulls()
  983. {
  984. $builder = $this->getBuilder();
  985. $builder->select('*')->from('users')->whereNull(['id', 'expires_at']);
  986. $this->assertSame('select * from "users" where "id" is null and "expires_at" is null', $builder->toSql());
  987. $this->assertEquals([], $builder->getBindings());
  988. $builder = $this->getBuilder();
  989. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereNull(['id', 'expires_at']);
  990. $this->assertSame('select * from "users" where "id" = ? or "id" is null or "expires_at" is null', $builder->toSql());
  991. $this->assertEquals([0 => 1], $builder->getBindings());
  992. }
  993. public function testBasicWhereNotNulls()
  994. {
  995. $builder = $this->getBuilder();
  996. $builder->select('*')->from('users')->whereNotNull('id');
  997. $this->assertSame('select * from "users" where "id" is not null', $builder->toSql());
  998. $this->assertEquals([], $builder->getBindings());
  999. $builder = $this->getBuilder();
  1000. $builder->select('*')->from('users')->where('id', '>', 1)->orWhereNotNull('id');
  1001. $this->assertSame('select * from "users" where "id" > ? or "id" is not null', $builder->toSql());
  1002. $this->assertEquals([0 => 1], $builder->getBindings());
  1003. }
  1004. public function testArrayWhereNotNulls()
  1005. {
  1006. $builder = $this->getBuilder();
  1007. $builder->select('*')->from('users')->whereNotNull(['id', 'expires_at']);
  1008. $this->assertSame('select * from "users" where "id" is not null and "expires_at" is not null', $builder->toSql());
  1009. $this->assertEquals([], $builder->getBindings());
  1010. $builder = $this->getBuilder();
  1011. $builder->select('*')->from('users')->where('id', '>', 1)->orWhereNotNull(['id', 'expires_at']);
  1012. $this->assertSame('select * from "users" where "id" > ? or "id" is not null or "expires_at" is not null', $builder->toSql());
  1013. $this->assertEquals([0 => 1], $builder->getBindings());
  1014. }
  1015. public function testGroupBys()
  1016. {
  1017. $builder = $this->getBuilder();
  1018. $builder->select('*')->from('users')->groupBy('email');
  1019. $this->assertSame('select * from "users" group by "email"', $builder->toSql());
  1020. $builder = $this->getBuilder();
  1021. $builder->select('*')->from('users')->groupBy('id', 'email');
  1022. $this->assertSame('select * from "users" group by "id", "email"', $builder->toSql());
  1023. $builder = $this->getBuilder();
  1024. $builder->select('*')->from('users')->groupBy(['id', 'email']);
  1025. $this->assertSame('select * from "users" group by "id", "email"', $builder->toSql());
  1026. $builder = $this->getBuilder();
  1027. $builder->select('*')->from('users')->groupBy(new Raw('DATE(created_at)'));
  1028. $this->assertSame('select * from "users" group by DATE(created_at)', $builder->toSql());
  1029. $builder = $this->getBuilder();
  1030. $builder->select('*')->from('users')->groupByRaw('DATE(created_at), ? DESC', ['foo']);
  1031. $this->assertSame('select * from "users" group by DATE(created_at), ? DESC', $builder->toSql());
  1032. $this->assertEquals(['foo'], $builder->getBindings());
  1033. $builder = $this->getBuilder();
  1034. $builder->havingRaw('?', ['havingRawBinding'])->groupByRaw('?', ['groupByRawBinding'])->whereRaw('?', ['whereRawBinding']);
  1035. $this->assertEquals(['whereRawBinding', 'groupByRawBinding', 'havingRawBinding'], $builder->getBindings());
  1036. }
  1037. public function testOrderBys()
  1038. {
  1039. $builder = $this->getBuilder();
  1040. $builder->select('*')->from('users')->orderBy('email')->orderBy('age', 'desc');
  1041. $this->assertSame('select * from "users" order by "email" asc, "age" desc', $builder->toSql());
  1042. $builder->orders = null;
  1043. $this->assertSame('select * from "users"', $builder->toSql());
  1044. $builder->orders = [];
  1045. $this->assertSame('select * from "users"', $builder->toSql());
  1046. $builder = $this->getBuilder();
  1047. $builder->select('*')->from('users')->orderBy('email')->orderByRaw('"age" ? desc', ['foo']);
  1048. $this->assertSame('select * from "users" order by "email" asc, "age" ? desc', $builder->toSql());
  1049. $this->assertEquals(['foo'], $builder->getBindings());
  1050. $builder = $this->getBuilder();
  1051. $builder->select('*')->from('users')->orderByDesc('name');
  1052. $this->assertSame('select * from "users" order by "name" desc', $builder->toSql());
  1053. $builder = $this->getBuilder();
  1054. $builder->select('*')->from('posts')->where('public', 1)
  1055. ->unionAll($this->getBuilder()->select('*')->from('videos')->where('public', 1))
  1056. ->orderByRaw('field(category, ?, ?) asc', ['news', 'opinion']);
  1057. $this->assertSame('(select * from "posts" where "public" = ?) union all (select * from "videos" where "public" = ?) order by field(category, ?, ?) asc', $builder->toSql());
  1058. $this->assertEquals([1, 1, 'news', 'opinion'], $builder->getBindings());
  1059. }
  1060. public function testOrderBysSqlServer()
  1061. {
  1062. $builder = $this->getSqlServerBuilder();
  1063. $builder->select('*')->from('users')->orderBy('email')->orderBy('age', 'desc');
  1064. $this->assertSame('select * from [users] order by [email] asc, [age] desc', $builder->toSql());
  1065. $builder->orders = null;
  1066. $this->assertSame('select * from [users]', $builder->toSql());
  1067. $builder->orders = [];
  1068. $this->assertSame('select * from [users]', $builder->toSql());
  1069. $builder = $this->getSqlServerBuilder();
  1070. $builder->select('*')->from('users')->orderBy('email');
  1071. $this->assertSame('select * from [users] order by [email] asc', $builder->toSql());
  1072. $builder = $this->getSqlServerBuilder();
  1073. $builder->select('*')->from('users')->orderByDesc('name');
  1074. $this->assertSame('select * from [users] order by [name] desc', $builder->toSql());
  1075. $builder = $this->getSqlServerBuilder();
  1076. $builder->select('*')->from('users')->orderByRaw('[age] asc');
  1077. $this->assertSame('select * from [users] order by [age] asc', $builder->toSql());
  1078. $builder = $this->getSqlServerBuilder();
  1079. $builder->select('*')->from('users')->orderBy('email')->orderByRaw('[age] ? desc', ['foo']);
  1080. $this->assertSame('select * from [users] order by [email] asc, [age] ? desc', $builder->toSql());
  1081. $this->assertEquals(['foo'], $builder->getBindings());
  1082. $builder = $this->getSqlServerBuilder();
  1083. $builder->select('*')->from('users')->skip(25)->take(10)->orderByRaw('[email] desc');
  1084. $this->assertSame('select * from [users] order by [email] desc offset 25 rows fetch next 10 rows only', $builder->toSql());
  1085. }
  1086. public function testReorder()
  1087. {
  1088. $builder = $this->getBuilder();
  1089. $builder->select('*')->from('users')->orderBy('name');
  1090. $this->assertSame('select * from "users" order by "name" asc', $builder->toSql());
  1091. $builder->reorder();
  1092. $this->assertSame('select * from "users"', $builder->toSql());
  1093. $builder = $this->getBuilder();
  1094. $builder->select('*')->from('users')->orderBy('name');
  1095. $this->assertSame('select * from "users" order by "name" asc', $builder->toSql());
  1096. $builder->reorder('email', 'desc');
  1097. $this->assertSame('select * from "users" order by "email" desc', $builder->toSql());
  1098. $builder = $this->getBuilder();
  1099. $builder->select('*')->from('first');
  1100. $builder->union($this->getBuilder()->select('*')->from('second'));
  1101. $builder->orderBy('name');
  1102. $this->assertSame('(select * from "first") union (select * from "second") order by "name" asc', $builder->toSql());
  1103. $builder->reorder();
  1104. $this->assertSame('(select * from "first") union (select * from "second")', $builder->toSql());
  1105. $builder = $this->getBuilder();
  1106. $builder->select('*')->from('users')->orderByRaw('?', [true]);
  1107. $this->assertEquals([true], $builder->getBindings());
  1108. $builder->reorder();
  1109. $this->assertEquals([], $builder->getBindings());
  1110. }
  1111. public function testOrderBySubQueries()
  1112. {
  1113. $expected = 'select * from "users" order by (select "created_at" from "logins" where "user_id" = "users"."id" limit 1)';
  1114. $subQuery = function ($query) {
  1115. return $query->select('created_at')->from('logins')->whereColumn('user_id', 'users.id')->limit(1);
  1116. };
  1117. $builder = $this->getBuilder()->select('*')->from('users')->orderBy($subQuery);
  1118. $this->assertSame("$expected asc", $builder->toSql());
  1119. $builder = $this->getBuilder()->select('*')->from('users')->orderBy($subQuery, 'desc');
  1120. $this->assertSame("$expected desc", $builder->toSql());
  1121. $builder = $this->getBuilder()->select('*')->from('users')->orderByDesc($subQuery);
  1122. $this->assertSame("$expected desc", $builder->toSql());
  1123. $builder = $this->getBuilder();
  1124. $builder->select('*')->from('posts')->where('public', 1)
  1125. ->unionAll($this->getBuilder()->select('*')->from('videos')->where('public', 1))
  1126. ->orderBy($this->getBuilder()->selectRaw('field(category, ?, ?)', ['news', 'opinion']));
  1127. $this->assertSame('(select * from "posts" where "public" = ?) union all (select * from "videos" where "public" = ?) order by (select field(category, ?, ?)) asc', $builder->toSql());
  1128. $this->assertEquals([1, 1, 'news', 'opinion'], $builder->getBindings());
  1129. }
  1130. public function testOrderByInvalidDirectionParam()
  1131. {
  1132. $this->expectException(InvalidArgumentException::class);
  1133. $builder = $this->getBuilder();
  1134. $builder->select('*')->from('users')->orderBy('age', 'asec');
  1135. }
  1136. public function testHavings()
  1137. {
  1138. $builder = $this->getBuilder();
  1139. $builder->select('*')->from('users')->having('email', '>', 1);
  1140. $this->assertSame('select * from "users" having "email" > ?', $builder->toSql());
  1141. $builder = $this->getBuilder();
  1142. $builder->select('*')->from('users')
  1143. ->orHaving('email', '=', 'test@example.com')
  1144. ->orHaving('email', '=', 'test2@example.com');
  1145. $this->assertSame('select * from "users" having "email" = ? or "email" = ?', $builder->toSql());
  1146. $builder = $this->getBuilder();
  1147. $builder->select('*')->from('users')->groupBy('email')->having('email', '>', 1);
  1148. $this->assertSame('select * from "users" group by "email" having "email" > ?', $builder->toSql());
  1149. $builder = $this->getBuilder();
  1150. $builder->select('email as foo_email')->from('users')->having('foo_email', '>', 1);
  1151. $this->assertSame('select "email" as "foo_email" from "users" having "foo_email" > ?', $builder->toSql());
  1152. $builder = $this->getBuilder();
  1153. $builder->select(['category', new Raw('count(*) as "total"')])->from('item')->where('department', '=', 'popular')->groupBy('category')->having('total', '>', new Raw('3'));
  1154. $this->assertSame('select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > 3', $builder->toSql());
  1155. $builder = $this->getBuilder();
  1156. $builder->select(['category', new Raw('count(*) as "total"')])->from('item')->where('department', '=', 'popular')->groupBy('category')->having('total', '>', 3);
  1157. $this->assertSame('select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > ?', $builder->toSql());
  1158. }
  1159. public function testHavingBetweens()
  1160. {
  1161. $builder = $this->getBuilder();
  1162. $builder->select('*')->from('users')->havingBetween('id', [1, 2, 3]);
  1163. $this->assertSame('select * from "users" having "id" between ? and ?', $builder->toSql());
  1164. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  1165. $builder = $this->getBuilder();
  1166. $builder->select('*')->from('users')->havingBetween('id', [[1, 2], [3, 4]]);
  1167. $this->assertSame('select * from "users" having "id" between ? and ?', $builder->toSql());
  1168. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  1169. }
  1170. public function testHavingShortcut()
  1171. {
  1172. $builder = $this->getBuilder();
  1173. $builder->select('*')->from('users')->having('email', 1)->orHaving('email', 2);
  1174. $this->assertSame('select * from "users" having "email" = ? or "email" = ?', $builder->toSql());
  1175. }
  1176. public function testHavingFollowedBySelectGet()
  1177. {
  1178. $builder = $this->getBuilder();
  1179. $query = 'select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > ?';
  1180. $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular', 3], true)->andReturn([['category' => 'rock', 'total' => 5]]);
  1181. $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {
  1182. return $results;
  1183. });
  1184. $builder->from('item');
  1185. $result = $builder->select(['category', new Raw('count(*) as "total"')])->where('department', '=', 'popular')->groupBy('category')->having('total', '>', 3)->get();
  1186. $this->assertEquals([['category' => 'rock', 'total' => 5]], $result->all());
  1187. // Using \Raw value
  1188. $builder = $this->getBuilder();
  1189. $query = 'select "category", count(*) as "total" from "item" where "department" = ? group by "category" having "total" > 3';
  1190. $builder->getConnection()->shouldReceive('select')->once()->with($query, ['popular'], true)->andReturn([['category' => 'rock', 'total' => 5]]);
  1191. $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {
  1192. return $results;
  1193. });
  1194. $builder->from('item');
  1195. $result = $builder->select(['category', new Raw('count(*) as "total"')])->where('department', '=', 'popular')->groupBy('category')->having('total', '>', new Raw('3'))->get();
  1196. $this->assertEquals([['category' => 'rock', 'total' => 5]], $result->all());
  1197. }
  1198. public function testRawHavings()
  1199. {
  1200. $builder = $this->getBuilder();
  1201. $builder->select('*')->from('users')->havingRaw('user_foo < user_bar');
  1202. $this->assertSame('select * from "users" having user_foo < user_bar', $builder->toSql());
  1203. $builder = $this->getBuilder();
  1204. $builder->select('*')->from('users')->having('baz', '=', 1)->orHavingRaw('user_foo < user_bar');
  1205. $this->assertSame('select * from "users" having "baz" = ? or user_foo < user_bar', $builder->toSql());
  1206. $builder = $this->getBuilder();
  1207. $builder->select('*')->from('users')->havingBetween('last_login_date', ['2018-11-16', '2018-12-16'])->orHavingRaw('user_foo < user_bar');
  1208. $this->assertSame('select * from "users" having "last_login_date" between ? and ? or user_foo < user_bar', $builder->toSql());
  1209. }
  1210. public function testLimitsAndOffsets()
  1211. {
  1212. $builder = $this->getBuilder();
  1213. $builder->select('*')->from('users')->offset(5)->limit(10);
  1214. $this->assertSame('select * from "users" limit 10 offset 5', $builder->toSql());
  1215. $builder = $this->getBuilder();
  1216. $builder->select('*')->from('users')->limit(null);
  1217. $this->assertSame('select * from "users"', $builder->toSql());
  1218. $builder = $this->getBuilder();
  1219. $builder->select('*')->from('users')->limit(0);
  1220. $this->assertSame('select * from "users" limit 0', $builder->toSql());
  1221. $builder = $this->getBuilder();
  1222. $builder->select('*')->from('users')->skip(5)->take(10);
  1223. $this->assertSame('select * from "users" limit 10 offset 5', $builder->toSql());
  1224. $builder = $this->getBuilder();
  1225. $builder->select('*')->from('users')->skip(0)->take(0);
  1226. $this->assertSame('select * from "users" limit 0 offset 0', $builder->toSql());
  1227. $builder = $this->getBuilder();
  1228. $builder->select('*')->from('users')->skip(-5)->take(-10);
  1229. $this->assertSame('select * from "users" offset 0', $builder->toSql());
  1230. $builder = $this->getBuilder();
  1231. $builder->select('*')->from('users')->skip(null)->take(null);
  1232. $this->assertSame('select * from "users" offset 0', $builder->toSql());
  1233. $builder = $this->getBuilder();
  1234. $builder->select('*')->from('users')->skip(5)->take(null);
  1235. $this->assertSame('select * from "users" offset 5', $builder->toSql());
  1236. }
  1237. public function testForPage()
  1238. {
  1239. $builder = $this->getBuilder();
  1240. $builder->select('*')->from('users')->forPage(2, 15);
  1241. $this->assertSame('select * from "users" limit 15 offset 15', $builder->toSql());
  1242. $builder = $this->getBuilder();
  1243. $builder->select('*')->from('users')->forPage(0, 15);
  1244. $this->assertSame('select * from "users" limit 15 offset 0', $builder->toSql());
  1245. $builder = $this->getBuilder();
  1246. $builder->select('*')->from('users')->forPage(-2, 15);
  1247. $this->assertSame('select * from "users" limit 15 offset 0', $builder->toSql());
  1248. $builder = $this->getBuilder();
  1249. $builder->select('*')->from('users')->forPage(2, 0);
  1250. $this->assertSame('select * from "users" limit 0 offset 0', $builder->toSql());
  1251. $builder = $this->getBuilder();
  1252. $builder->select('*')->from('users')->forPage(0, 0);
  1253. $this->assertSame('select * from "users" limit 0 offset 0', $builder->toSql());
  1254. $builder = $this->getBuilder();
  1255. $builder->select('*')->from('users')->forPage(-2, 0);
  1256. $this->assertSame('select * from "users" limit 0 offset 0', $builder->toSql());
  1257. }
  1258. public function testGetCountForPaginationWithBindings()
  1259. {
  1260. $builder = $this->getBuilder();
  1261. $builder->from('users')->selectSub(function ($q) {
  1262. $q->select('body')->from('posts')->where('id', 4);
  1263. }, 'post');
  1264. $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]);
  1265. $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {
  1266. return $results;
  1267. });
  1268. $count = $builder->getCountForPagination();
  1269. $this->assertEquals(1, $count);
  1270. $this->assertEquals([4], $builder->getBindings());
  1271. }
  1272. public function testGetCountForPaginationWithColumnAliases()
  1273. {
  1274. $builder = $this->getBuilder();
  1275. $columns = ['body as post_body', 'teaser', 'posts.created as published'];
  1276. $builder->from('posts')->select($columns);
  1277. $builder->getConnection()->shouldReceive('select')->once()->with('select count("body", "teaser", "posts"."created") as aggregate from "posts"', [], true)->andReturn([['aggregate' => 1]]);
  1278. $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {
  1279. return $results;
  1280. });
  1281. $count = $builder->getCountForPagination($columns);
  1282. $this->assertEquals(1, $count);
  1283. }
  1284. public function testGetCountForPaginationWithUnion()
  1285. {
  1286. $builder = $this->getBuilder();
  1287. $builder->from('posts')->select('id')->union($this->getBuilder()->from('videos')->select('id'));
  1288. $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from ((select "id" from "posts") union (select "id" from "videos")) as "temp_table"', [], true)->andReturn([['aggregate' => 1]]);
  1289. $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {
  1290. return $results;
  1291. });
  1292. $count = $builder->getCountForPagination();
  1293. $this->assertEquals(1, $count);
  1294. }
  1295. public function testWhereShortcut()
  1296. {
  1297. $builder = $this->getBuilder();
  1298. $builder->select('*')->from('users')->where('id', 1)->orWhere('name', 'foo');
  1299. $this->assertSame('select * from "users" where "id" = ? or "name" = ?', $builder->toSql());
  1300. $this->assertEquals([0 => 1, 1 => 'foo'], $builder->getBindings());
  1301. }
  1302. public function testWhereWithArrayConditions()
  1303. {
  1304. $builder = $this->getBuilder();
  1305. $builder->select('*')->from('users')->where([['foo', 1], ['bar', 2]]);
  1306. $this->assertSame('select * from "users" where ("foo" = ? and "bar" = ?)', $builder->toSql());
  1307. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  1308. $builder = $this->getBuilder();
  1309. $builder->select('*')->from('users')->where(['foo' => 1, 'bar' => 2]);
  1310. $this->assertSame('select * from "users" where ("foo" = ? and "bar" = ?)', $builder->toSql());
  1311. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  1312. $builder = $this->getBuilder();
  1313. $builder->select('*')->from('users')->where([['foo', 1], ['bar', '<', 2]]);
  1314. $this->assertSame('select * from "users" where ("foo" = ? and "bar" < ?)', $builder->toSql());
  1315. $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings());
  1316. }
  1317. public function testNestedWheres()
  1318. {
  1319. $builder = $this->getBuilder();
  1320. $builder->select('*')->from('users')->where('email', '=', 'foo')->orWhere(function ($q) {
  1321. $q->where('name', '=', 'bar')->where('age', '=', 25);
  1322. });
  1323. $this->assertSame('select * from "users" where "email" = ? or ("name" = ? and "age" = ?)', $builder->toSql());
  1324. $this->assertEquals([0 => 'foo', 1 => 'bar', 2 => 25], $builder->getBindings());
  1325. }
  1326. public function testNestedWhereBindings()
  1327. {
  1328. $builder = $this->getBuilder();
  1329. $builder->where('email', '=', 'foo')->where(function ($q) {
  1330. $q->selectRaw('?', ['ignore'])->where('name', '=', 'bar');
  1331. });
  1332. $this->assertEquals([0 => 'foo', 1 => 'bar'], $builder->getBindings());
  1333. }
  1334. public function testFullSubSelects()
  1335. {
  1336. $builder = $this->getBuilder();
  1337. $builder->select('*')->from('users')->where('email', '=', 'foo')->orWhere('id', '=', function ($q) {
  1338. $q->select(new Raw('max(id)'))->from('users')->where('email', '=', 'bar');
  1339. });
  1340. $this->assertSame('select * from "users" where "email" = ? or "id" = (select max(id) from "users" where "email" = ?)', $builder->toSql());
  1341. $this->assertEquals([0 => 'foo', 1 => 'bar'], $builder->getBindings());
  1342. }
  1343. public function testWhereExists()
  1344. {
  1345. $builder = $this->getBuilder();
  1346. $builder->select('*')->from('orders')->whereExists(function ($q) {
  1347. $q->select('*')->from('products')->where('products.id', '=', new Raw('"orders"."id"'));
  1348. });
  1349. $this->assertSame('select * from "orders" where exists (select * from "products" where "products"."id" = "orders"."id")', $builder->toSql());
  1350. $builder = $this->getBuilder();
  1351. $builder->select('*')->from('orders')->whereNotExists(function ($q) {
  1352. $q->select('*')->from('products')->where('products.id', '=', new Raw('"orders"."id"'));
  1353. });
  1354. $this->assertSame('select * from "orders" where not exists (select * from "products" where "products"."id" = "orders"."id")', $builder->toSql());
  1355. $builder = $this->getBuilder();
  1356. $builder->select('*')->from('orders')->where('id', '=', 1)->orWhereExists(function ($q) {
  1357. $q->select('*')->from('products')->where('products.id', '=', new Raw('"orders"."id"'));
  1358. });
  1359. $this->assertSame('select * from "orders" where "id" = ? or exists (select * from "products" where "products"."id" = "orders"."id")', $builder->toSql());
  1360. $builder = $this->getBuilder();
  1361. $builder->select('*')->from('orders')->where('id', '=', 1)->orWhereNotExists(function ($q) {
  1362. $q->select('*')->from('products')->where('products.id', '=', new Raw('"orders"."id"'));
  1363. });
  1364. $this->assertSame('select * from "orders" where "id" = ? or not exists (select * from "products" where "products"."id" = "orders"."id")', $builder->toSql());
  1365. }
  1366. public function testBasicJoins()
  1367. {
  1368. $builder = $this->getBuilder();
  1369. $builder->select('*')->from('users')->join('contacts', 'users.id', 'contacts.id');
  1370. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id"', $builder->toSql());
  1371. $builder = $this->getBuilder();
  1372. $builder->select('*')->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->leftJoin('photos', 'users.id', '=', 'photos.id');
  1373. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" left join "photos" on "users"."id" = "photos"."id"', $builder->toSql());
  1374. $builder = $this->getBuilder();
  1375. $builder->select('*')->from('users')->leftJoinWhere('photos', 'users.id', '=', 'bar')->joinWhere('photos', 'users.id', '=', 'foo');
  1376. $this->assertSame('select * from "users" left join "photos" on "users"."id" = ? inner join "photos" on "users"."id" = ?', $builder->toSql());
  1377. $this->assertEquals(['bar', 'foo'], $builder->getBindings());
  1378. }
  1379. public function testCrossJoins()
  1380. {
  1381. $builder = $this->getBuilder();
  1382. $builder->select('*')->from('sizes')->crossJoin('colors');
  1383. $this->assertSame('select * from "sizes" cross join "colors"', $builder->toSql());
  1384. $builder = $this->getBuilder();
  1385. $builder->select('*')->from('tableB')->join('tableA', 'tableA.column1', '=', 'tableB.column2', 'cross');
  1386. $this->assertSame('select * from "tableB" cross join "tableA" on "tableA"."column1" = "tableB"."column2"', $builder->toSql());
  1387. $builder = $this->getBuilder();
  1388. $builder->select('*')->from('tableB')->crossJoin('tableA', 'tableA.column1', '=', 'tableB.column2');
  1389. $this->assertSame('select * from "tableB" cross join "tableA" on "tableA"."column1" = "tableB"."column2"', $builder->toSql());
  1390. }
  1391. public function testCrossJoinSubs()
  1392. {
  1393. $builder = $this->getBuilder();
  1394. $builder->selectRaw('(sale / overall.sales) * 100 AS percent_of_total')->from('sales')->crossJoinSub($this->getBuilder()->selectRaw('SUM(sale) AS sales')->from('sales'), 'overall');
  1395. $this->assertSame('select (sale / overall.sales) * 100 AS percent_of_total from "sales" cross join (select SUM(sale) AS sales from "sales") as "overall"', $builder->toSql());
  1396. }
  1397. public function testComplexJoin()
  1398. {
  1399. $builder = $this->getBuilder();
  1400. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1401. $j->on('users.id', '=', 'contacts.id')->orOn('users.name', '=', 'contacts.name');
  1402. });
  1403. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" or "users"."name" = "contacts"."name"', $builder->toSql());
  1404. $builder = $this->getBuilder();
  1405. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1406. $j->where('users.id', '=', 'foo')->orWhere('users.name', '=', 'bar');
  1407. });
  1408. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = ? or "users"."name" = ?', $builder->toSql());
  1409. $this->assertEquals(['foo', 'bar'], $builder->getBindings());
  1410. // Run the assertions again
  1411. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = ? or "users"."name" = ?', $builder->toSql());
  1412. $this->assertEquals(['foo', 'bar'], $builder->getBindings());
  1413. }
  1414. public function testJoinWhereNull()
  1415. {
  1416. $builder = $this->getBuilder();
  1417. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1418. $j->on('users.id', '=', 'contacts.id')->whereNull('contacts.deleted_at');
  1419. });
  1420. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."deleted_at" is null', $builder->toSql());
  1421. $builder = $this->getBuilder();
  1422. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1423. $j->on('users.id', '=', 'contacts.id')->orWhereNull('contacts.deleted_at');
  1424. });
  1425. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" or "contacts"."deleted_at" is null', $builder->toSql());
  1426. }
  1427. public function testJoinWhereNotNull()
  1428. {
  1429. $builder = $this->getBuilder();
  1430. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1431. $j->on('users.id', '=', 'contacts.id')->whereNotNull('contacts.deleted_at');
  1432. });
  1433. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."deleted_at" is not null', $builder->toSql());
  1434. $builder = $this->getBuilder();
  1435. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1436. $j->on('users.id', '=', 'contacts.id')->orWhereNotNull('contacts.deleted_at');
  1437. });
  1438. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" or "contacts"."deleted_at" is not null', $builder->toSql());
  1439. }
  1440. public function testJoinWhereIn()
  1441. {
  1442. $builder = $this->getBuilder();
  1443. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1444. $j->on('users.id', '=', 'contacts.id')->whereIn('contacts.name', [48, 'baz', null]);
  1445. });
  1446. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."name" in (?, ?, ?)', $builder->toSql());
  1447. $this->assertEquals([48, 'baz', null], $builder->getBindings());
  1448. $builder = $this->getBuilder();
  1449. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1450. $j->on('users.id', '=', 'contacts.id')->orWhereIn('contacts.name', [48, 'baz', null]);
  1451. });
  1452. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" or "contacts"."name" in (?, ?, ?)', $builder->toSql());
  1453. $this->assertEquals([48, 'baz', null], $builder->getBindings());
  1454. }
  1455. public function testJoinWhereInSubquery()
  1456. {
  1457. $builder = $this->getBuilder();
  1458. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1459. $q = $this->getBuilder();
  1460. $q->select('name')->from('contacts')->where('name', 'baz');
  1461. $j->on('users.id', '=', 'contacts.id')->whereIn('contacts.name', $q);
  1462. });
  1463. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."name" in (select "name" from "contacts" where "name" = ?)', $builder->toSql());
  1464. $this->assertEquals(['baz'], $builder->getBindings());
  1465. $builder = $this->getBuilder();
  1466. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1467. $q = $this->getBuilder();
  1468. $q->select('name')->from('contacts')->where('name', 'baz');
  1469. $j->on('users.id', '=', 'contacts.id')->orWhereIn('contacts.name', $q);
  1470. });
  1471. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" or "contacts"."name" in (select "name" from "contacts" where "name" = ?)', $builder->toSql());
  1472. $this->assertEquals(['baz'], $builder->getBindings());
  1473. }
  1474. public function testJoinWhereNotIn()
  1475. {
  1476. $builder = $this->getBuilder();
  1477. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1478. $j->on('users.id', '=', 'contacts.id')->whereNotIn('contacts.name', [48, 'baz', null]);
  1479. });
  1480. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."name" not in (?, ?, ?)', $builder->toSql());
  1481. $this->assertEquals([48, 'baz', null], $builder->getBindings());
  1482. $builder = $this->getBuilder();
  1483. $builder->select('*')->from('users')->join('contacts', function ($j) {
  1484. $j->on('users.id', '=', 'contacts.id')->orWhereNotIn('contacts.name', [48, 'baz', null]);
  1485. });
  1486. $this->assertSame('select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" or "contacts"."name" not in (?, ?, ?)', $builder->toSql());
  1487. $this->assertEquals([48, 'baz', null], $builder->getBindings());
  1488. }
  1489. public function testJoinsWithNestedConditions()
  1490. {
  1491. $builder = $this->getBuilder();
  1492. $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {
  1493. $j->on('users.id', '=', 'contacts.id')->where(function ($j) {
  1494. $j->where('contacts.country', '=', 'US')->orWhere('contacts.is_partner', '=', 1);
  1495. });
  1496. });
  1497. $this->assertSame('select * from "users" left join "contacts" on "users"."id" = "contacts"."id" and ("contacts"."country" = ? or "contacts"."is_partner" = ?)', $builder->toSql());
  1498. $this->assertEquals(['US', 1], $builder->getBindings());
  1499. $builder = $this->getBuilder();
  1500. $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {
  1501. $j->on('users.id', '=', 'contacts.id')->where('contacts.is_active', '=', 1)->orOn(function ($j) {
  1502. $j->orWhere(function ($j) {
  1503. $j->where('contacts.country', '=', 'UK')->orOn('contacts.type', '=', 'users.type');
  1504. })->where(function ($j) {
  1505. $j->where('contacts.country', '=', 'US')->orWhereNull('contacts.is_partner');
  1506. });
  1507. });
  1508. });
  1509. $this->assertSame('select * from "users" left join "contacts" on "users"."id" = "contacts"."id" and "contacts"."is_active" = ? or (("contacts"."country" = ? or "contacts"."type" = "users"."type") and ("contacts"."country" = ? or "contacts"."is_partner" is null))', $builder->toSql());
  1510. $this->assertEquals([1, 'UK', 'US'], $builder->getBindings());
  1511. }
  1512. public function testJoinsWithAdvancedConditions()
  1513. {
  1514. $builder = $this->getBuilder();
  1515. $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {
  1516. $j->on('users.id', 'contacts.id')->where(function ($j) {
  1517. $j->whereRole('admin')
  1518. ->orWhereNull('contacts.disabled')
  1519. ->orWhereRaw('year(contacts.created_at) = 2016');
  1520. });
  1521. });
  1522. $this->assertSame('select * from "users" left join "contacts" on "users"."id" = "contacts"."id" and ("role" = ? or "contacts"."disabled" is null or year(contacts.created_at) = 2016)', $builder->toSql());
  1523. $this->assertEquals(['admin'], $builder->getBindings());
  1524. }
  1525. public function testJoinsWithSubqueryCondition()
  1526. {
  1527. $builder = $this->getBuilder();
  1528. $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {
  1529. $j->on('users.id', 'contacts.id')->whereIn('contact_type_id', function ($q) {
  1530. $q->select('id')->from('contact_types')
  1531. ->where('category_id', '1')
  1532. ->whereNull('deleted_at');
  1533. });
  1534. });
  1535. $this->assertSame('select * from "users" left join "contacts" on "users"."id" = "contacts"."id" and "contact_type_id" in (select "id" from "contact_types" where "category_id" = ? and "deleted_at" is null)', $builder->toSql());
  1536. $this->assertEquals(['1'], $builder->getBindings());
  1537. $builder = $this->getBuilder();
  1538. $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {
  1539. $j->on('users.id', 'contacts.id')->whereExists(function ($q) {
  1540. $q->selectRaw('1')->from('contact_types')
  1541. ->whereRaw('contact_types.id = contacts.contact_type_id')
  1542. ->where('category_id', '1')
  1543. ->whereNull('deleted_at');
  1544. });
  1545. });
  1546. $this->assertSame('select * from "users" left join "contacts" on "users"."id" = "contacts"."id" and exists (select 1 from "contact_types" where contact_types.id = contacts.contact_type_id and "category_id" = ? and "deleted_at" is null)', $builder->toSql());
  1547. $this->assertEquals(['1'], $builder->getBindings());
  1548. }
  1549. public function testJoinsWithAdvancedSubqueryCondition()
  1550. {
  1551. $builder = $this->getBuilder();
  1552. $builder->select('*')->from('users')->leftJoin('contacts', function ($j) {
  1553. $j->on('users.id', 'contacts.id')->whereExists(function ($q) {
  1554. $q->selectRaw('1')->from('contact_types')
  1555. ->whereRaw('contact_types.id = contacts.contact_type_id')
  1556. ->where('category_id', '1')
  1557. ->whereNull('deleted_at')
  1558. ->whereIn('level_id', function ($q) {
  1559. $q->select('id')->from('levels')
  1560. ->where('is_active', true);
  1561. });
  1562. });
  1563. });
  1564. $this->assertSame('select * from "users" left join "contacts" on "users"."id" = "contacts"."id" and exists (select 1 from "contact_types" where contact_types.id = contacts.contact_type_id and "category_id" = ? and "deleted_at" is null and "level_id" in (select "id" from "levels" where "is_active" = ?))', $builder->toSql());
  1565. $this->assertEquals(['1', true], $builder->getBindings());
  1566. }
  1567. public function testJoinsWithNestedJoins()
  1568. {
  1569. $builder = $this->getBuilder();
  1570. $builder->select('users.id', 'contacts.id', 'contact_types.id')->from('users')->leftJoin('contacts', function ($j) {
  1571. $j->on('users.id', 'contacts.id')->join('contact_types', 'contacts.contact_type_id', '=', 'contact_types.id');
  1572. });
  1573. $this->assertSame('select "users"."id", "contacts"."id", "contact_types"."id" from "users" left join ("contacts" inner join "contact_types" on "contacts"."contact_type_id" = "contact_types"."id") on "users"."id" = "contacts"."id"', $builder->toSql());
  1574. }
  1575. public function testJoinsWithMultipleNestedJoins()
  1576. {
  1577. $builder = $this->getBuilder();
  1578. $builder->select('users.id', 'contacts.id', 'contact_types.id', 'countrys.id', 'planets.id')->from('users')->leftJoin('contacts', function ($j) {
  1579. $j->on('users.id', 'contacts.id')
  1580. ->join('contact_types', 'contacts.contact_type_id', '=', 'contact_types.id')
  1581. ->leftJoin('countrys', function ($q) {
  1582. $q->on('contacts.country', '=', 'countrys.country')
  1583. ->join('planets', function ($q) {
  1584. $q->on('countrys.planet_id', '=', 'planet.id')
  1585. ->where('planet.is_settled', '=', 1)
  1586. ->where('planet.population', '>=', 10000);
  1587. });
  1588. });
  1589. });
  1590. $this->assertSame('select "users"."id", "contacts"."id", "contact_types"."id", "countrys"."id", "planets"."id" from "users" left join ("contacts" inner join "contact_types" on "contacts"."contact_type_id" = "contact_types"."id" left join ("countrys" inner join "planets" on "countrys"."planet_id" = "planet"."id" and "planet"."is_settled" = ? and "planet"."population" >= ?) on "contacts"."country" = "countrys"."country") on "users"."id" = "contacts"."id"', $builder->toSql());
  1591. $this->assertEquals(['1', 10000], $builder->getBindings());
  1592. }
  1593. public function testJoinsWithNestedJoinWithAdvancedSubqueryCondition()
  1594. {
  1595. $builder = $this->getBuilder();
  1596. $builder->select('users.id', 'contacts.id', 'contact_types.id')->from('users')->leftJoin('contacts', function ($j) {
  1597. $j->on('users.id', 'contacts.id')
  1598. ->join('contact_types', 'contacts.contact_type_id', '=', 'contact_types.id')
  1599. ->whereExists(function ($q) {
  1600. $q->select('*')->from('countrys')
  1601. ->whereColumn('contacts.country', '=', 'countrys.country')
  1602. ->join('planets', function ($q) {
  1603. $q->on('countrys.planet_id', '=', 'planet.id')
  1604. ->where('planet.is_settled', '=', 1);
  1605. })
  1606. ->where('planet.population', '>=', 10000);
  1607. });
  1608. });
  1609. $this->assertSame('select "users"."id", "contacts"."id", "contact_types"."id" from "users" left join ("contacts" inner join "contact_types" on "contacts"."contact_type_id" = "contact_types"."id") on "users"."id" = "contacts"."id" and exists (select * from "countrys" inner join "planets" on "countrys"."planet_id" = "planet"."id" and "planet"."is_settled" = ? where "contacts"."country" = "countrys"."country" and "planet"."population" >= ?)', $builder->toSql());
  1610. $this->assertEquals(['1', 10000], $builder->getBindings());
  1611. }
  1612. public function testJoinSub()
  1613. {
  1614. $builder = $this->getBuilder();
  1615. $builder->from('users')->joinSub('select * from "contacts"', 'sub', 'users.id', '=', 'sub.id');
  1616. $this->assertSame('select * from "users" inner join (select * from "contacts") as "sub" on "users"."id" = "sub"."id"', $builder->toSql());
  1617. $builder = $this->getBuilder();
  1618. $builder->from('users')->joinSub(function ($q) {
  1619. $q->from('contacts');
  1620. }, 'sub', 'users.id', '=', 'sub.id');
  1621. $this->assertSame('select * from "users" inner join (select * from "contacts") as "sub" on "users"."id" = "sub"."id"', $builder->toSql());
  1622. $builder = $this->getBuilder();
  1623. $eloquentBuilder = new EloquentBuilder($this->getBuilder()->from('contacts'));
  1624. $builder->from('users')->joinSub($eloquentBuilder, 'sub', 'users.id', '=', 'sub.id');
  1625. $this->assertSame('select * from "users" inner join (select * from "contacts") as "sub" on "users"."id" = "sub"."id"', $builder->toSql());
  1626. $builder = $this->getBuilder();
  1627. $sub1 = $this->getBuilder()->from('contacts')->where('name', 'foo');
  1628. $sub2 = $this->getBuilder()->from('contacts')->where('name', 'bar');
  1629. $builder->from('users')
  1630. ->joinSub($sub1, 'sub1', 'users.id', '=', 1, 'inner', true)
  1631. ->joinSub($sub2, 'sub2', 'users.id', '=', 'sub2.user_id');
  1632. $expected = 'select * from "users" ';
  1633. $expected .= 'inner join (select * from "contacts" where "name" = ?) as "sub1" on "users"."id" = ? ';
  1634. $expected .= 'inner join (select * from "contacts" where "name" = ?) as "sub2" on "users"."id" = "sub2"."user_id"';
  1635. $this->assertEquals($expected, $builder->toSql());
  1636. $this->assertEquals(['foo', 1, 'bar'], $builder->getRawBindings()['join']);
  1637. $this->expectException(InvalidArgumentException::class);
  1638. $builder = $this->getBuilder();
  1639. $builder->from('users')->joinSub(['foo'], 'sub', 'users.id', '=', 'sub.id');
  1640. }
  1641. public function testJoinSubWithPrefix()
  1642. {
  1643. $builder = $this->getBuilder();
  1644. $builder->getGrammar()->setTablePrefix('prefix_');
  1645. $builder->from('users')->joinSub('select * from "contacts"', 'sub', 'users.id', '=', 'sub.id');
  1646. $this->assertSame('select * from "prefix_users" inner join (select * from "contacts") as "prefix_sub" on "prefix_users"."id" = "prefix_sub"."id"', $builder->toSql());
  1647. }
  1648. public function testLeftJoinSub()
  1649. {
  1650. $builder = $this->getBuilder();
  1651. $builder->from('users')->leftJoinSub($this->getBuilder()->from('contacts'), 'sub', 'users.id', '=', 'sub.id');
  1652. $this->assertSame('select * from "users" left join (select * from "contacts") as "sub" on "users"."id" = "sub"."id"', $builder->toSql());
  1653. $this->expectException(InvalidArgumentException::class);
  1654. $builder = $this->getBuilder();
  1655. $builder->from('users')->leftJoinSub(['foo'], 'sub', 'users.id', '=', 'sub.id');
  1656. }
  1657. public function testRightJoinSub()
  1658. {
  1659. $builder = $this->getBuilder();
  1660. $builder->from('users')->rightJoinSub($this->getBuilder()->from('contacts'), 'sub', 'users.id', '=', 'sub.id');
  1661. $this->assertSame('select * from "users" right join (select * from "contacts") as "sub" on "users"."id" = "sub"."id"', $builder->toSql());
  1662. $this->expectException(InvalidArgumentException::class);
  1663. $builder = $this->getBuilder();
  1664. $builder->from('users')->rightJoinSub(['foo'], 'sub', 'users.id', '=', 'sub.id');
  1665. }
  1666. public function testRawExpressionsInSelect()
  1667. {
  1668. $builder = $this->getBuilder();
  1669. $builder->select(new Raw('substr(foo, 6)'))->from('users');
  1670. $this->assertSame('select substr(foo, 6) from "users"', $builder->toSql());
  1671. }
  1672. public function testFindReturnsFirstResultByID()
  1673. {
  1674. $builder = $this->getBuilder();
  1675. $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]);
  1676. $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) {
  1677. return $results;
  1678. });
  1679. $results = $builder->from('users')->find(1);
  1680. $this->assertEquals(['foo' => 'bar'], $results);
  1681. }
  1682. public function testFirstMethodReturnsFirstResult()
  1683. {
  1684. $builder = $this->getBuilder();
  1685. $builder->getConnection()->shouldReceive('select')->once()->with('select * from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]);
  1686. $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturnUsing(function ($query, $results) {
  1687. return $results;
  1688. });
  1689. $results = $builder->from('users')->where('id', '=', 1)->first();
  1690. $this->assertEquals(['foo' => 'bar'], $results);
  1691. }
  1692. public function testPluckMethodGetsCollectionOfColumnValues()
  1693. {
  1694. $builder = $this->getBuilder();
  1695. $builder->getConnection()->shouldReceive('select')->once()->andReturn([['foo' => 'bar'], ['foo' => 'baz']]);
  1696. $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar'], ['foo' => 'baz']])->andReturnUsing(function ($query, $results) {
  1697. return $results;
  1698. });
  1699. $results = $builder->from('users')->where('id', '=', 1)->pluck('foo');
  1700. $this->assertEquals(['bar', 'baz'], $results->all());
  1701. $builder = $this->getBuilder();
  1702. $builder->getConnection()->shouldReceive('select')->once()->andReturn([['id' => 1, 'foo' => 'bar'], ['id' => 10, 'foo' => 'baz']]);
  1703. $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['id' => 1, 'foo' => 'bar'], ['id' => 10, 'foo' => 'baz']])->andReturnUsing(function ($query, $results) {
  1704. return $results;
  1705. });
  1706. $results = $builder->from('users')->where('id', '=', 1)->pluck('foo', 'id');
  1707. $this->assertEquals([1 => 'bar', 10 => 'baz'], $results->all());
  1708. }
  1709. public function testImplode()
  1710. {
  1711. // Test without glue.
  1712. $builder = $this->getBuilder();
  1713. $builder->getConnection()->shouldReceive('select')->once()->andReturn([['foo' => 'bar'], ['foo' => 'baz']]);
  1714. $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar'], ['foo' => 'baz']])->andReturnUsing(function ($query, $results) {
  1715. return $results;
  1716. });
  1717. $results = $builder->from('users')->where('id', '=', 1)->implode('foo');
  1718. $this->assertSame('barbaz', $results);
  1719. // Test with glue.
  1720. $builder = $this->getBuilder();
  1721. $builder->getConnection()->shouldReceive('select')->once()->andReturn([['foo' => 'bar'], ['foo' => 'baz']]);
  1722. $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar'], ['foo' => 'baz']])->andReturnUsing(function ($query, $results) {
  1723. return $results;
  1724. });
  1725. $results = $builder->from('users')->where('id', '=', 1)->implode('foo', ',');
  1726. $this->assertSame('bar,baz', $results);
  1727. }
  1728. public function testValueMethodReturnsSingleColumn()
  1729. {
  1730. $builder = $this->getBuilder();
  1731. $builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ? limit 1', [1], true)->andReturn([['foo' => 'bar']]);
  1732. $builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturn([['foo' => 'bar']]);
  1733. $results = $builder->from('users')->where('id', '=', 1)->value('foo');
  1734. $this->assertSame('bar', $results);
  1735. }
  1736. public function testAggregateFunctions()
  1737. {
  1738. $builder = $this->getBuilder();
  1739. $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]);
  1740. $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {
  1741. return $results;
  1742. });
  1743. $results = $builder->from('users')->count();
  1744. $this->assertEquals(1, $results);
  1745. $builder = $this->getBuilder();
  1746. $builder->getConnection()->shouldReceive('select')->once()->with('select exists(select * from "users") as "exists"', [], true)->andReturn([['exists' => 1]]);
  1747. $results = $builder->from('users')->exists();
  1748. $this->assertTrue($results);
  1749. $builder = $this->getBuilder();
  1750. $builder->getConnection()->shouldReceive('select')->once()->with('select exists(select * from "users") as "exists"', [], true)->andReturn([['exists' => 0]]);
  1751. $results = $builder->from('users')->doesntExist();
  1752. $this->assertTrue($results);
  1753. $builder = $this->getBuilder();
  1754. $builder->getConnection()->shouldReceive('select')->once()->with('select max("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]);
  1755. $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {
  1756. return $results;
  1757. });
  1758. $results = $builder->from('users')->max('id');
  1759. $this->assertEquals(1, $results);
  1760. $builder = $this->getBuilder();
  1761. $builder->getConnection()->shouldReceive('select')->once()->with('select min("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]);
  1762. $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {
  1763. return $results;
  1764. });
  1765. $results = $builder->from('users')->min('id');
  1766. $this->assertEquals(1, $results);
  1767. $builder = $this->getBuilder();
  1768. $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]);
  1769. $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {
  1770. return $results;
  1771. });
  1772. $results = $builder->from('users')->sum('id');
  1773. $this->assertEquals(1, $results);
  1774. }
  1775. public function testSqlServerExists()
  1776. {
  1777. $builder = $this->getSqlServerBuilder();
  1778. $builder->getConnection()->shouldReceive('select')->once()->with('select top 1 1 [exists] from [users]', [], true)->andReturn([['exists' => 1]]);
  1779. $results = $builder->from('users')->exists();
  1780. $this->assertTrue($results);
  1781. }
  1782. public function testExistsOr()
  1783. {
  1784. $builder = $this->getBuilder();
  1785. $builder->getConnection()->shouldReceive('select')->andReturn([['exists' => 1]]);
  1786. $results = $builder->from('users')->doesntExistOr(function () {
  1787. return 123;
  1788. });
  1789. $this->assertSame(123, $results);
  1790. $builder = $this->getBuilder();
  1791. $builder->getConnection()->shouldReceive('select')->andReturn([['exists' => 0]]);
  1792. $results = $builder->from('users')->doesntExistOr(function () {
  1793. throw new RuntimeException;
  1794. });
  1795. $this->assertTrue($results);
  1796. }
  1797. public function testDoesntExistsOr()
  1798. {
  1799. $builder = $this->getBuilder();
  1800. $builder->getConnection()->shouldReceive('select')->andReturn([['exists' => 0]]);
  1801. $results = $builder->from('users')->existsOr(function () {
  1802. return 123;
  1803. });
  1804. $this->assertSame(123, $results);
  1805. $builder = $this->getBuilder();
  1806. $builder->getConnection()->shouldReceive('select')->andReturn([['exists' => 1]]);
  1807. $results = $builder->from('users')->existsOr(function () {
  1808. throw new RuntimeException;
  1809. });
  1810. $this->assertTrue($results);
  1811. }
  1812. public function testAggregateResetFollowedByGet()
  1813. {
  1814. $builder = $this->getBuilder();
  1815. $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]);
  1816. $builder->getConnection()->shouldReceive('select')->once()->with('select sum("id") as aggregate from "users"', [], true)->andReturn([['aggregate' => 2]]);
  1817. $builder->getConnection()->shouldReceive('select')->once()->with('select "column1", "column2" from "users"', [], true)->andReturn([['column1' => 'foo', 'column2' => 'bar']]);
  1818. $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {
  1819. return $results;
  1820. });
  1821. $builder->from('users')->select('column1', 'column2');
  1822. $count = $builder->count();
  1823. $this->assertEquals(1, $count);
  1824. $sum = $builder->sum('id');
  1825. $this->assertEquals(2, $sum);
  1826. $result = $builder->get();
  1827. $this->assertEquals([['column1' => 'foo', 'column2' => 'bar']], $result->all());
  1828. }
  1829. public function testAggregateResetFollowedBySelectGet()
  1830. {
  1831. $builder = $this->getBuilder();
  1832. $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]);
  1833. $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true)->andReturn([['column2' => 'foo', 'column3' => 'bar']]);
  1834. $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {
  1835. return $results;
  1836. });
  1837. $builder->from('users');
  1838. $count = $builder->count('column1');
  1839. $this->assertEquals(1, $count);
  1840. $result = $builder->select('column2', 'column3')->get();
  1841. $this->assertEquals([['column2' => 'foo', 'column3' => 'bar']], $result->all());
  1842. }
  1843. public function testAggregateResetFollowedByGetWithColumns()
  1844. {
  1845. $builder = $this->getBuilder();
  1846. $builder->getConnection()->shouldReceive('select')->once()->with('select count("column1") as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]);
  1847. $builder->getConnection()->shouldReceive('select')->once()->with('select "column2", "column3" from "users"', [], true)->andReturn([['column2' => 'foo', 'column3' => 'bar']]);
  1848. $builder->getProcessor()->shouldReceive('processSelect')->andReturnUsing(function ($builder, $results) {
  1849. return $results;
  1850. });
  1851. $builder->from('users');
  1852. $count = $builder->count('column1');
  1853. $this->assertEquals(1, $count);
  1854. $result = $builder->get(['column2', 'column3']);
  1855. $this->assertEquals([['column2' => 'foo', 'column3' => 'bar']], $result->all());
  1856. }
  1857. public function testAggregateWithSubSelect()
  1858. {
  1859. $builder = $this->getBuilder();
  1860. $builder->getConnection()->shouldReceive('select')->once()->with('select count(*) as aggregate from "users"', [], true)->andReturn([['aggregate' => 1]]);
  1861. $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) {
  1862. return $results;
  1863. });
  1864. $builder->from('users')->selectSub(function ($query) {
  1865. $query->from('posts')->select('foo', 'bar')->where('title', 'foo');
  1866. }, 'post');
  1867. $count = $builder->count();
  1868. $this->assertEquals(1, $count);
  1869. $this->assertSame('(select "foo", "bar" from "posts" where "title" = ?) as "post"', $builder->columns[0]->getValue());
  1870. $this->assertEquals(['foo'], $builder->getBindings());
  1871. }
  1872. public function testSubqueriesBindings()
  1873. {
  1874. $builder = $this->getBuilder();
  1875. $second = $this->getBuilder()->select('*')->from('users')->orderByRaw('id = ?', 2);
  1876. $third = $this->getBuilder()->select('*')->from('users')->where('id', 3)->groupBy('id')->having('id', '!=', 4);
  1877. $builder->groupBy('a')->having('a', '=', 1)->union($second)->union($third);
  1878. $this->assertEquals([0 => 1, 1 => 2, 2 => 3, 3 => 4], $builder->getBindings());
  1879. $builder = $this->getBuilder()->select('*')->from('users')->where('email', '=', function ($q) {
  1880. $q->select(new Raw('max(id)'))
  1881. ->from('users')->where('email', '=', 'bar')
  1882. ->orderByRaw('email like ?', '%.com')
  1883. ->groupBy('id')->having('id', '=', 4);
  1884. })->orWhere('id', '=', 'foo')->groupBy('id')->having('id', '=', 5);
  1885. $this->assertEquals([0 => 'bar', 1 => 4, 2 => '%.com', 3 => 'foo', 4 => 5], $builder->getBindings());
  1886. }
  1887. public function testInsertMethod()
  1888. {
  1889. $builder = $this->getBuilder();
  1890. $builder->getConnection()->shouldReceive('insert')->once()->with('insert into "users" ("email") values (?)', ['foo'])->andReturn(true);
  1891. $result = $builder->from('users')->insert(['email' => 'foo']);
  1892. $this->assertTrue($result);
  1893. }
  1894. public function testInsertUsingMethod()
  1895. {
  1896. $builder = $this->getBuilder();
  1897. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into "table1" ("foo") select "bar" from "table2" where "foreign_id" = ?', [5])->andReturn(1);
  1898. $result = $builder->from('table1')->insertUsing(
  1899. ['foo'],
  1900. function (Builder $query) {
  1901. $query->select(['bar'])->from('table2')->where('foreign_id', '=', 5);
  1902. }
  1903. );
  1904. $this->assertEquals(1, $result);
  1905. }
  1906. public function testInsertUsingInvalidSubquery()
  1907. {
  1908. $this->expectException(InvalidArgumentException::class);
  1909. $builder = $this->getBuilder();
  1910. $builder->from('table1')->insertUsing(['foo'], ['bar']);
  1911. }
  1912. public function testInsertOrIgnoreMethod()
  1913. {
  1914. $this->expectException(RuntimeException::class);
  1915. $this->expectExceptionMessage('does not support');
  1916. $builder = $this->getBuilder();
  1917. $builder->from('users')->insertOrIgnore(['email' => 'foo']);
  1918. }
  1919. public function testMySqlInsertOrIgnoreMethod()
  1920. {
  1921. $builder = $this->getMySqlBuilder();
  1922. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert ignore into `users` (`email`) values (?)', ['foo'])->andReturn(1);
  1923. $result = $builder->from('users')->insertOrIgnore(['email' => 'foo']);
  1924. $this->assertEquals(1, $result);
  1925. }
  1926. public function testPostgresInsertOrIgnoreMethod()
  1927. {
  1928. $builder = $this->getPostgresBuilder();
  1929. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into "users" ("email") values (?) on conflict do nothing', ['foo'])->andReturn(1);
  1930. $result = $builder->from('users')->insertOrIgnore(['email' => 'foo']);
  1931. $this->assertEquals(1, $result);
  1932. }
  1933. public function testSQLiteInsertOrIgnoreMethod()
  1934. {
  1935. $builder = $this->getSQLiteBuilder();
  1936. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert or ignore into "users" ("email") values (?)', ['foo'])->andReturn(1);
  1937. $result = $builder->from('users')->insertOrIgnore(['email' => 'foo']);
  1938. $this->assertEquals(1, $result);
  1939. }
  1940. public function testSqlServerInsertOrIgnoreMethod()
  1941. {
  1942. $this->expectException(RuntimeException::class);
  1943. $this->expectExceptionMessage('does not support');
  1944. $builder = $this->getSqlServerBuilder();
  1945. $builder->from('users')->insertOrIgnore(['email' => 'foo']);
  1946. }
  1947. public function testInsertGetIdMethod()
  1948. {
  1949. $builder = $this->getBuilder();
  1950. $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into "users" ("email") values (?)', ['foo'], 'id')->andReturn(1);
  1951. $result = $builder->from('users')->insertGetId(['email' => 'foo'], 'id');
  1952. $this->assertEquals(1, $result);
  1953. }
  1954. public function testInsertGetIdMethodRemovesExpressions()
  1955. {
  1956. $builder = $this->getBuilder();
  1957. $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into "users" ("email", "bar") values (?, bar)', ['foo'], 'id')->andReturn(1);
  1958. $result = $builder->from('users')->insertGetId(['email' => 'foo', 'bar' => new Raw('bar')], 'id');
  1959. $this->assertEquals(1, $result);
  1960. }
  1961. public function testInsertGetIdWithEmptyValues()
  1962. {
  1963. $builder = $this->getMySqlBuilder();
  1964. $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into `users` () values ()', [], null);
  1965. $builder->from('users')->insertGetId([]);
  1966. $builder = $this->getPostgresBuilder();
  1967. $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into "users" default values returning "id"', [], null);
  1968. $builder->from('users')->insertGetId([]);
  1969. $builder = $this->getSQLiteBuilder();
  1970. $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into "users" default values', [], null);
  1971. $builder->from('users')->insertGetId([]);
  1972. $builder = $this->getSqlServerBuilder();
  1973. $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into [users] default values', [], null);
  1974. $builder->from('users')->insertGetId([]);
  1975. }
  1976. public function testInsertMethodRespectsRawBindings()
  1977. {
  1978. $builder = $this->getBuilder();
  1979. $builder->getConnection()->shouldReceive('insert')->once()->with('insert into "users" ("email") values (CURRENT TIMESTAMP)', [])->andReturn(true);
  1980. $result = $builder->from('users')->insert(['email' => new Raw('CURRENT TIMESTAMP')]);
  1981. $this->assertTrue($result);
  1982. }
  1983. public function testMultipleInsertsWithExpressionValues()
  1984. {
  1985. $builder = $this->getBuilder();
  1986. $builder->getConnection()->shouldReceive('insert')->once()->with('insert into "users" ("email") values (UPPER(\'Foo\')), (LOWER(\'Foo\'))', [])->andReturn(true);
  1987. $result = $builder->from('users')->insert([['email' => new Raw("UPPER('Foo')")], ['email' => new Raw("LOWER('Foo')")]]);
  1988. $this->assertTrue($result);
  1989. }
  1990. public function testUpdateMethod()
  1991. {
  1992. $builder = $this->getBuilder();
  1993. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? where "id" = ?', ['foo', 'bar', 1])->andReturn(1);
  1994. $result = $builder->from('users')->where('id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);
  1995. $this->assertEquals(1, $result);
  1996. $builder = $this->getMySqlBuilder();
  1997. $builder->getConnection()->shouldReceive('update')->once()->with('update `users` set `email` = ?, `name` = ? where `id` = ? order by `foo` desc limit 5', ['foo', 'bar', 1])->andReturn(1);
  1998. $result = $builder->from('users')->where('id', '=', 1)->orderBy('foo', 'desc')->limit(5)->update(['email' => 'foo', 'name' => 'bar']);
  1999. $this->assertEquals(1, $result);
  2000. }
  2001. public function testUpsertMethod()
  2002. {
  2003. $builder = $this->getMySqlBuilder();
  2004. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into `users` (`email`, `name`) values (?, ?), (?, ?) on duplicate key update `email` = values(`email`), `name` = values(`name`)', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);
  2005. $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email');
  2006. $this->assertEquals(2, $result);
  2007. $builder = $this->getPostgresBuilder();
  2008. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into "users" ("email", "name") values (?, ?), (?, ?) on conflict ("email") do update set "email" = "excluded"."email", "name" = "excluded"."name"', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);
  2009. $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email');
  2010. $this->assertEquals(2, $result);
  2011. $builder = $this->getSQLiteBuilder();
  2012. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into "users" ("email", "name") values (?, ?), (?, ?) on conflict ("email") do update set "email" = "excluded"."email", "name" = "excluded"."name"', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);
  2013. $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email');
  2014. $this->assertEquals(2, $result);
  2015. $builder = $this->getSqlServerBuilder();
  2016. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('merge [users] using (values (?, ?), (?, ?)) [laravel_source] ([email], [name]) on [laravel_source].[email] = [users].[email] when matched then update set [email] = [laravel_source].[email], [name] = [laravel_source].[name] when not matched then insert ([email], [name]) values ([email], [name]);', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);
  2017. $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email');
  2018. $this->assertEquals(2, $result);
  2019. }
  2020. public function testUpsertMethodWithUpdateColumns()
  2021. {
  2022. $builder = $this->getMySqlBuilder();
  2023. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into `users` (`email`, `name`) values (?, ?), (?, ?) on duplicate key update `name` = values(`name`)', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);
  2024. $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']);
  2025. $this->assertEquals(2, $result);
  2026. $builder = $this->getPostgresBuilder();
  2027. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into "users" ("email", "name") values (?, ?), (?, ?) on conflict ("email") do update set "name" = "excluded"."name"', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);
  2028. $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']);
  2029. $this->assertEquals(2, $result);
  2030. $builder = $this->getSQLiteBuilder();
  2031. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into "users" ("email", "name") values (?, ?), (?, ?) on conflict ("email") do update set "name" = "excluded"."name"', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);
  2032. $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']);
  2033. $this->assertEquals(2, $result);
  2034. $builder = $this->getSqlServerBuilder();
  2035. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('merge [users] using (values (?, ?), (?, ?)) [laravel_source] ([email], [name]) on [laravel_source].[email] = [users].[email] when matched then update set [name] = [laravel_source].[name] when not matched then insert ([email], [name]) values ([email], [name]);', ['foo', 'bar', 'foo2', 'bar2'])->andReturn(2);
  2036. $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']);
  2037. $this->assertEquals(2, $result);
  2038. }
  2039. public function testUpdateMethodWithJoins()
  2040. {
  2041. $builder = $this->getBuilder();
  2042. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" inner join "orders" on "users"."id" = "orders"."user_id" set "email" = ?, "name" = ? where "users"."id" = ?', ['foo', 'bar', 1])->andReturn(1);
  2043. $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);
  2044. $this->assertEquals(1, $result);
  2045. $builder = $this->getBuilder();
  2046. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" inner join "orders" on "users"."id" = "orders"."user_id" and "users"."id" = ? set "email" = ?, "name" = ?', [1, 'foo', 'bar'])->andReturn(1);
  2047. $result = $builder->from('users')->join('orders', function ($join) {
  2048. $join->on('users.id', '=', 'orders.user_id')
  2049. ->where('users.id', '=', 1);
  2050. })->update(['email' => 'foo', 'name' => 'bar']);
  2051. $this->assertEquals(1, $result);
  2052. }
  2053. public function testUpdateMethodWithJoinsOnSqlServer()
  2054. {
  2055. $builder = $this->getSqlServerBuilder();
  2056. $builder->getConnection()->shouldReceive('update')->once()->with('update [users] set [email] = ?, [name] = ? from [users] inner join [orders] on [users].[id] = [orders].[user_id] where [users].[id] = ?', ['foo', 'bar', 1])->andReturn(1);
  2057. $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);
  2058. $this->assertEquals(1, $result);
  2059. $builder = $this->getSqlServerBuilder();
  2060. $builder->getConnection()->shouldReceive('update')->once()->with('update [users] set [email] = ?, [name] = ? from [users] inner join [orders] on [users].[id] = [orders].[user_id] and [users].[id] = ?', ['foo', 'bar', 1])->andReturn(1);
  2061. $result = $builder->from('users')->join('orders', function ($join) {
  2062. $join->on('users.id', '=', 'orders.user_id')
  2063. ->where('users.id', '=', 1);
  2064. })->update(['email' => 'foo', 'name' => 'bar']);
  2065. $this->assertEquals(1, $result);
  2066. }
  2067. public function testUpdateMethodWithJoinsOnMySql()
  2068. {
  2069. $builder = $this->getMySqlBuilder();
  2070. $builder->getConnection()->shouldReceive('update')->once()->with('update `users` inner join `orders` on `users`.`id` = `orders`.`user_id` set `email` = ?, `name` = ? where `users`.`id` = ?', ['foo', 'bar', 1])->andReturn(1);
  2071. $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);
  2072. $this->assertEquals(1, $result);
  2073. $builder = $this->getMySqlBuilder();
  2074. $builder->getConnection()->shouldReceive('update')->once()->with('update `users` inner join `orders` on `users`.`id` = `orders`.`user_id` and `users`.`id` = ? set `email` = ?, `name` = ?', [1, 'foo', 'bar'])->andReturn(1);
  2075. $result = $builder->from('users')->join('orders', function ($join) {
  2076. $join->on('users.id', '=', 'orders.user_id')
  2077. ->where('users.id', '=', 1);
  2078. })->update(['email' => 'foo', 'name' => 'bar']);
  2079. $this->assertEquals(1, $result);
  2080. }
  2081. public function testUpdateMethodWithJoinsOnSQLite()
  2082. {
  2083. $builder = $this->getSQLiteBuilder();
  2084. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? where "rowid" in (select "users"."rowid" from "users" where "users"."id" > ? order by "id" asc limit 3)', ['foo', 'bar', 1])->andReturn(1);
  2085. $result = $builder->from('users')->where('users.id', '>', 1)->limit(3)->oldest('id')->update(['email' => 'foo', 'name' => 'bar']);
  2086. $this->assertEquals(1, $result);
  2087. $builder = $this->getSQLiteBuilder();
  2088. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? where "rowid" in (select "users"."rowid" from "users" inner join "orders" on "users"."id" = "orders"."user_id" where "users"."id" = ?)', ['foo', 'bar', 1])->andReturn(1);
  2089. $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);
  2090. $this->assertEquals(1, $result);
  2091. $builder = $this->getSQLiteBuilder();
  2092. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? where "rowid" in (select "users"."rowid" from "users" inner join "orders" on "users"."id" = "orders"."user_id" and "users"."id" = ?)', ['foo', 'bar', 1])->andReturn(1);
  2093. $result = $builder->from('users')->join('orders', function ($join) {
  2094. $join->on('users.id', '=', 'orders.user_id')
  2095. ->where('users.id', '=', 1);
  2096. })->update(['email' => 'foo', 'name' => 'bar']);
  2097. $this->assertEquals(1, $result);
  2098. $builder = $this->getSQLiteBuilder();
  2099. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" as "u" set "email" = ?, "name" = ? where "rowid" in (select "u"."rowid" from "users" as "u" inner join "orders" as "o" on "u"."id" = "o"."user_id")', ['foo', 'bar'])->andReturn(1);
  2100. $result = $builder->from('users as u')->join('orders as o', 'u.id', '=', 'o.user_id')->update(['email' => 'foo', 'name' => 'bar']);
  2101. $this->assertEquals(1, $result);
  2102. }
  2103. public function testUpdateMethodWithJoinsAndAliasesOnSqlServer()
  2104. {
  2105. $builder = $this->getSqlServerBuilder();
  2106. $builder->getConnection()->shouldReceive('update')->once()->with('update [u] set [email] = ?, [name] = ? from [users] as [u] inner join [orders] on [u].[id] = [orders].[user_id] where [u].[id] = ?', ['foo', 'bar', 1])->andReturn(1);
  2107. $result = $builder->from('users as u')->join('orders', 'u.id', '=', 'orders.user_id')->where('u.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);
  2108. $this->assertEquals(1, $result);
  2109. }
  2110. public function testUpdateMethodWithoutJoinsOnPostgres()
  2111. {
  2112. $builder = $this->getPostgresBuilder();
  2113. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? where "id" = ?', ['foo', 'bar', 1])->andReturn(1);
  2114. $result = $builder->from('users')->where('id', '=', 1)->update(['users.email' => 'foo', 'name' => 'bar']);
  2115. $this->assertEquals(1, $result);
  2116. $builder = $this->getPostgresBuilder();
  2117. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? where "id" = ?', ['foo', 'bar', 1])->andReturn(1);
  2118. $result = $builder->from('users')->where('id', '=', 1)->selectRaw('?', ['ignore'])->update(['users.email' => 'foo', 'name' => 'bar']);
  2119. $this->assertEquals(1, $result);
  2120. $builder = $this->getPostgresBuilder();
  2121. $builder->getConnection()->shouldReceive('update')->once()->with('update "users"."users" set "email" = ?, "name" = ? where "id" = ?', ['foo', 'bar', 1])->andReturn(1);
  2122. $result = $builder->from('users.users')->where('id', '=', 1)->selectRaw('?', ['ignore'])->update(['users.users.email' => 'foo', 'name' => 'bar']);
  2123. $this->assertEquals(1, $result);
  2124. }
  2125. public function testUpdateMethodWithJoinsOnPostgres()
  2126. {
  2127. $builder = $this->getPostgresBuilder();
  2128. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? where "ctid" in (select "users"."ctid" from "users" inner join "orders" on "users"."id" = "orders"."user_id" where "users"."id" = ?)', ['foo', 'bar', 1])->andReturn(1);
  2129. $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->update(['email' => 'foo', 'name' => 'bar']);
  2130. $this->assertEquals(1, $result);
  2131. $builder = $this->getPostgresBuilder();
  2132. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? where "ctid" in (select "users"."ctid" from "users" inner join "orders" on "users"."id" = "orders"."user_id" and "users"."id" = ?)', ['foo', 'bar', 1])->andReturn(1);
  2133. $result = $builder->from('users')->join('orders', function ($join) {
  2134. $join->on('users.id', '=', 'orders.user_id')
  2135. ->where('users.id', '=', 1);
  2136. })->update(['email' => 'foo', 'name' => 'bar']);
  2137. $this->assertEquals(1, $result);
  2138. $builder = $this->getPostgresBuilder();
  2139. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? where "ctid" in (select "users"."ctid" from "users" inner join "orders" on "users"."id" = "orders"."user_id" and "users"."id" = ? where "name" = ?)', ['foo', 'bar', 1, 'baz'])->andReturn(1);
  2140. $result = $builder->from('users')
  2141. ->join('orders', function ($join) {
  2142. $join->on('users.id', '=', 'orders.user_id')
  2143. ->where('users.id', '=', 1);
  2144. })->where('name', 'baz')
  2145. ->update(['email' => 'foo', 'name' => 'bar']);
  2146. $this->assertEquals(1, $result);
  2147. }
  2148. public function testUpdateFromMethodWithJoinsOnPostgres()
  2149. {
  2150. $builder = $this->getPostgresBuilder();
  2151. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? from "orders" where "users"."id" = ? and "users"."id" = "orders"."user_id"', ['foo', 'bar', 1])->andReturn(1);
  2152. $result = $builder->from('users')->join('orders', 'users.id', '=', 'orders.user_id')->where('users.id', '=', 1)->updateFrom(['email' => 'foo', 'name' => 'bar']);
  2153. $this->assertEquals(1, $result);
  2154. $builder = $this->getPostgresBuilder();
  2155. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? from "orders" where "users"."id" = "orders"."user_id" and "users"."id" = ?', ['foo', 'bar', 1])->andReturn(1);
  2156. $result = $builder->from('users')->join('orders', function ($join) {
  2157. $join->on('users.id', '=', 'orders.user_id')
  2158. ->where('users.id', '=', 1);
  2159. })->updateFrom(['email' => 'foo', 'name' => 'bar']);
  2160. $this->assertEquals(1, $result);
  2161. $builder = $this->getPostgresBuilder();
  2162. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ?, "name" = ? from "orders" where "name" = ? and "users"."id" = "orders"."user_id" and "users"."id" = ?', ['foo', 'bar', 'baz', 1])->andReturn(1);
  2163. $result = $builder->from('users')
  2164. ->join('orders', function ($join) {
  2165. $join->on('users.id', '=', 'orders.user_id')
  2166. ->where('users.id', '=', 1);
  2167. })->where('name', 'baz')
  2168. ->updateFrom(['email' => 'foo', 'name' => 'bar']);
  2169. $this->assertEquals(1, $result);
  2170. }
  2171. public function testUpdateMethodRespectsRaw()
  2172. {
  2173. $builder = $this->getBuilder();
  2174. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = foo, "name" = ? where "id" = ?', ['bar', 1])->andReturn(1);
  2175. $result = $builder->from('users')->where('id', '=', 1)->update(['email' => new Raw('foo'), 'name' => 'bar']);
  2176. $this->assertEquals(1, $result);
  2177. }
  2178. public function testUpdateOrInsertMethod()
  2179. {
  2180. $builder = m::mock(Builder::class.'[where,exists,insert]', [
  2181. m::mock(ConnectionInterface::class),
  2182. new Grammar,
  2183. m::mock(Processor::class),
  2184. ]);
  2185. $builder->shouldReceive('where')->once()->with(['email' => 'foo'])->andReturn(m::self());
  2186. $builder->shouldReceive('exists')->once()->andReturn(false);
  2187. $builder->shouldReceive('insert')->once()->with(['email' => 'foo', 'name' => 'bar'])->andReturn(true);
  2188. $this->assertTrue($builder->updateOrInsert(['email' => 'foo'], ['name' => 'bar']));
  2189. $builder = m::mock(Builder::class.'[where,exists,update]', [
  2190. m::mock(ConnectionInterface::class),
  2191. new Grammar,
  2192. m::mock(Processor::class),
  2193. ]);
  2194. $builder->shouldReceive('where')->once()->with(['email' => 'foo'])->andReturn(m::self());
  2195. $builder->shouldReceive('exists')->once()->andReturn(true);
  2196. $builder->shouldReceive('take')->andReturnSelf();
  2197. $builder->shouldReceive('update')->once()->with(['name' => 'bar'])->andReturn(1);
  2198. $this->assertTrue($builder->updateOrInsert(['email' => 'foo'], ['name' => 'bar']));
  2199. }
  2200. public function testUpdateOrInsertMethodWorksWithEmptyUpdateValues()
  2201. {
  2202. $builder = m::spy(Builder::class.'[where,exists,update]', [
  2203. m::mock(ConnectionInterface::class),
  2204. new Grammar,
  2205. m::mock(Processor::class),
  2206. ]);
  2207. $builder->shouldReceive('where')->once()->with(['email' => 'foo'])->andReturn(m::self());
  2208. $builder->shouldReceive('exists')->once()->andReturn(true);
  2209. $this->assertTrue($builder->updateOrInsert(['email' => 'foo']));
  2210. $builder->shouldNotHaveReceived('update');
  2211. }
  2212. public function testDeleteMethod()
  2213. {
  2214. $builder = $this->getBuilder();
  2215. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "email" = ?', ['foo'])->andReturn(1);
  2216. $result = $builder->from('users')->where('email', '=', 'foo')->delete();
  2217. $this->assertEquals(1, $result);
  2218. $builder = $this->getBuilder();
  2219. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "users"."id" = ?', [1])->andReturn(1);
  2220. $result = $builder->from('users')->delete(1);
  2221. $this->assertEquals(1, $result);
  2222. $builder = $this->getBuilder();
  2223. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "users"."id" = ?', [1])->andReturn(1);
  2224. $result = $builder->from('users')->selectRaw('?', ['ignore'])->delete(1);
  2225. $this->assertEquals(1, $result);
  2226. $builder = $this->getSqliteBuilder();
  2227. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "rowid" in (select "users"."rowid" from "users" where "email" = ? order by "id" asc limit 1)', ['foo'])->andReturn(1);
  2228. $result = $builder->from('users')->where('email', '=', 'foo')->orderBy('id')->take(1)->delete();
  2229. $this->assertEquals(1, $result);
  2230. $builder = $this->getMySqlBuilder();
  2231. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from `users` where `email` = ? order by `id` asc limit 1', ['foo'])->andReturn(1);
  2232. $result = $builder->from('users')->where('email', '=', 'foo')->orderBy('id')->take(1)->delete();
  2233. $this->assertEquals(1, $result);
  2234. $builder = $this->getSqlServerBuilder();
  2235. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from [users] where [email] = ?', ['foo'])->andReturn(1);
  2236. $result = $builder->from('users')->where('email', '=', 'foo')->delete();
  2237. $this->assertEquals(1, $result);
  2238. $builder = $this->getSqlServerBuilder();
  2239. $builder->getConnection()->shouldReceive('delete')->once()->with('delete top (1) from [users] where [email] = ?', ['foo'])->andReturn(1);
  2240. $result = $builder->from('users')->where('email', '=', 'foo')->orderBy('id')->take(1)->delete();
  2241. $this->assertEquals(1, $result);
  2242. }
  2243. public function testDeleteWithJoinMethod()
  2244. {
  2245. $builder = $this->getSqliteBuilder();
  2246. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "rowid" in (select "users"."rowid" from "users" inner join "contacts" on "users"."id" = "contacts"."id" where "users"."email" = ? order by "users"."id" asc limit 1)', ['foo'])->andReturn(1);
  2247. $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->where('users.email', '=', 'foo')->orderBy('users.id')->limit(1)->delete();
  2248. $this->assertEquals(1, $result);
  2249. $builder = $this->getSqliteBuilder();
  2250. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" as "u" where "rowid" in (select "u"."rowid" from "users" as "u" inner join "contacts" as "c" on "u"."id" = "c"."id")', [])->andReturn(1);
  2251. $result = $builder->from('users as u')->join('contacts as c', 'u.id', '=', 'c.id')->delete();
  2252. $this->assertEquals(1, $result);
  2253. $builder = $this->getMySqlBuilder();
  2254. $builder->getConnection()->shouldReceive('delete')->once()->with('delete `users` from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` where `email` = ?', ['foo'])->andReturn(1);
  2255. $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->where('email', '=', 'foo')->orderBy('id')->limit(1)->delete();
  2256. $this->assertEquals(1, $result);
  2257. $builder = $this->getMySqlBuilder();
  2258. $builder->getConnection()->shouldReceive('delete')->once()->with('delete `a` from `users` as `a` inner join `users` as `b` on `a`.`id` = `b`.`user_id` where `email` = ?', ['foo'])->andReturn(1);
  2259. $result = $builder->from('users AS a')->join('users AS b', 'a.id', '=', 'b.user_id')->where('email', '=', 'foo')->orderBy('id')->limit(1)->delete();
  2260. $this->assertEquals(1, $result);
  2261. $builder = $this->getMySqlBuilder();
  2262. $builder->getConnection()->shouldReceive('delete')->once()->with('delete `users` from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` where `users`.`id` = ?', [1])->andReturn(1);
  2263. $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->orderBy('id')->take(1)->delete(1);
  2264. $this->assertEquals(1, $result);
  2265. $builder = $this->getSqlServerBuilder();
  2266. $builder->getConnection()->shouldReceive('delete')->once()->with('delete [users] from [users] inner join [contacts] on [users].[id] = [contacts].[id] where [email] = ?', ['foo'])->andReturn(1);
  2267. $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->where('email', '=', 'foo')->delete();
  2268. $this->assertEquals(1, $result);
  2269. $builder = $this->getSqlServerBuilder();
  2270. $builder->getConnection()->shouldReceive('delete')->once()->with('delete [a] from [users] as [a] inner join [users] as [b] on [a].[id] = [b].[user_id] where [email] = ?', ['foo'])->andReturn(1);
  2271. $result = $builder->from('users AS a')->join('users AS b', 'a.id', '=', 'b.user_id')->where('email', '=', 'foo')->orderBy('id')->limit(1)->delete();
  2272. $this->assertEquals(1, $result);
  2273. $builder = $this->getSqlServerBuilder();
  2274. $builder->getConnection()->shouldReceive('delete')->once()->with('delete [users] from [users] inner join [contacts] on [users].[id] = [contacts].[id] where [users].[id] = ?', [1])->andReturn(1);
  2275. $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->delete(1);
  2276. $this->assertEquals(1, $result);
  2277. $builder = $this->getPostgresBuilder();
  2278. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "ctid" in (select "users"."ctid" from "users" inner join "contacts" on "users"."id" = "contacts"."id" where "users"."email" = ?)', ['foo'])->andReturn(1);
  2279. $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->where('users.email', '=', 'foo')->delete();
  2280. $this->assertEquals(1, $result);
  2281. $builder = $this->getPostgresBuilder();
  2282. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" as "a" where "ctid" in (select "a"."ctid" from "users" as "a" inner join "users" as "b" on "a"."id" = "b"."user_id" where "email" = ? order by "id" asc limit 1)', ['foo'])->andReturn(1);
  2283. $result = $builder->from('users AS a')->join('users AS b', 'a.id', '=', 'b.user_id')->where('email', '=', 'foo')->orderBy('id')->limit(1)->delete();
  2284. $this->assertEquals(1, $result);
  2285. $builder = $this->getPostgresBuilder();
  2286. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "ctid" in (select "users"."ctid" from "users" inner join "contacts" on "users"."id" = "contacts"."id" where "users"."id" = ? order by "id" asc limit 1)', [1])->andReturn(1);
  2287. $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->orderBy('id')->take(1)->delete(1);
  2288. $this->assertEquals(1, $result);
  2289. $builder = $this->getPostgresBuilder();
  2290. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "ctid" in (select "users"."ctid" from "users" inner join "contacts" on "users"."id" = "contacts"."user_id" and "users"."id" = ? where "name" = ?)', [1, 'baz'])->andReturn(1);
  2291. $result = $builder->from('users')
  2292. ->join('contacts', function ($join) {
  2293. $join->on('users.id', '=', 'contacts.user_id')
  2294. ->where('users.id', '=', 1);
  2295. })->where('name', 'baz')
  2296. ->delete();
  2297. $this->assertEquals(1, $result);
  2298. $builder = $this->getPostgresBuilder();
  2299. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "ctid" in (select "users"."ctid" from "users" inner join "contacts" on "users"."id" = "contacts"."id")', [])->andReturn(1);
  2300. $result = $builder->from('users')->join('contacts', 'users.id', '=', 'contacts.id')->delete();
  2301. $this->assertEquals(1, $result);
  2302. }
  2303. public function testTruncateMethod()
  2304. {
  2305. $builder = $this->getBuilder();
  2306. $builder->getConnection()->shouldReceive('statement')->once()->with('truncate table "users"', []);
  2307. $builder->from('users')->truncate();
  2308. $sqlite = new SQLiteGrammar;
  2309. $builder = $this->getBuilder();
  2310. $builder->from('users');
  2311. $this->assertEquals([
  2312. 'delete from sqlite_sequence where name = ?' => ['users'],
  2313. 'delete from "users"' => [],
  2314. ], $sqlite->compileTruncate($builder));
  2315. }
  2316. public function testPreserveAddsClosureToArray()
  2317. {
  2318. $builder = $this->getBuilder();
  2319. $builder->beforeQuery(function () {
  2320. });
  2321. $this->assertCount(1, $builder->beforeQueryCallbacks);
  2322. $this->assertInstanceOf(Closure::class, $builder->beforeQueryCallbacks[0]);
  2323. }
  2324. public function testApplyPreserveCleansArray()
  2325. {
  2326. $builder = $this->getBuilder();
  2327. $builder->beforeQuery(function () {
  2328. });
  2329. $this->assertCount(1, $builder->beforeQueryCallbacks);
  2330. $builder->applyBeforeQueryCallbacks();
  2331. $this->assertCount(0, $builder->beforeQueryCallbacks);
  2332. }
  2333. public function testPreservedAreAppliedByToSql()
  2334. {
  2335. $builder = $this->getBuilder();
  2336. $builder->beforeQuery(function ($builder) {
  2337. $builder->where('foo', 'bar');
  2338. });
  2339. $this->assertSame('select * where "foo" = ?', $builder->toSql());
  2340. $this->assertEquals(['bar'], $builder->getBindings());
  2341. }
  2342. public function testPreservedAreAppliedByInsert()
  2343. {
  2344. $builder = $this->getBuilder();
  2345. $builder->getConnection()->shouldReceive('insert')->once()->with('insert into "users" ("email") values (?)', ['foo']);
  2346. $builder->beforeQuery(function ($builder) {
  2347. $builder->from('users');
  2348. });
  2349. $builder->insert(['email' => 'foo']);
  2350. }
  2351. public function testPreservedAreAppliedByInsertGetId()
  2352. {
  2353. $this->called = false;
  2354. $builder = $this->getBuilder();
  2355. $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into "users" ("email") values (?)', ['foo'], 'id');
  2356. $builder->beforeQuery(function ($builder) {
  2357. $builder->from('users');
  2358. });
  2359. $builder->insertGetId(['email' => 'foo'], 'id');
  2360. }
  2361. public function testPreservedAreAppliedByInsertUsing()
  2362. {
  2363. $builder = $this->getBuilder();
  2364. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into "users" () select *', []);
  2365. $builder->beforeQuery(function ($builder) {
  2366. $builder->from('users');
  2367. });
  2368. $builder->insertUsing([], $this->getBuilder());
  2369. }
  2370. public function testPreservedAreAppliedByUpsert()
  2371. {
  2372. $builder = $this->getMySqlBuilder();
  2373. $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into `users` (`email`) values (?) on duplicate key update `email` = values(`email`)', ['foo']);
  2374. $builder->beforeQuery(function ($builder) {
  2375. $builder->from('users');
  2376. });
  2377. $builder->upsert(['email' => 'foo'], 'id');
  2378. }
  2379. public function testPreservedAreAppliedByUpdate()
  2380. {
  2381. $builder = $this->getBuilder();
  2382. $builder->getConnection()->shouldReceive('update')->once()->with('update "users" set "email" = ? where "id" = ?', ['foo', 1]);
  2383. $builder->from('users')->beforeQuery(function ($builder) {
  2384. $builder->where('id', 1);
  2385. });
  2386. $builder->update(['email' => 'foo']);
  2387. }
  2388. public function testPreservedAreAppliedByDelete()
  2389. {
  2390. $builder = $this->getBuilder();
  2391. $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users"', []);
  2392. $builder->beforeQuery(function ($builder) {
  2393. $builder->from('users');
  2394. });
  2395. $builder->delete();
  2396. }
  2397. public function testPreservedAreAppliedByTruncate()
  2398. {
  2399. $builder = $this->getBuilder();
  2400. $builder->getConnection()->shouldReceive('statement')->once()->with('truncate table "users"', []);
  2401. $builder->beforeQuery(function ($builder) {
  2402. $builder->from('users');
  2403. });
  2404. $builder->truncate();
  2405. }
  2406. public function testPreservedAreAppliedByExists()
  2407. {
  2408. $builder = $this->getBuilder();
  2409. $builder->getConnection()->shouldReceive('select')->once()->with('select exists(select * from "users") as "exists"', [], true);
  2410. $builder->beforeQuery(function ($builder) {
  2411. $builder->from('users');
  2412. });
  2413. $builder->exists();
  2414. }
  2415. public function testPostgresInsertGetId()
  2416. {
  2417. $builder = $this->getPostgresBuilder();
  2418. $builder->getProcessor()->shouldReceive('processInsertGetId')->once()->with($builder, 'insert into "users" ("email") values (?) returning "id"', ['foo'], 'id')->andReturn(1);
  2419. $result = $builder->from('users')->insertGetId(['email' => 'foo'], 'id');
  2420. $this->assertEquals(1, $result);
  2421. }
  2422. public function testMySqlWrapping()
  2423. {
  2424. $builder = $this->getMySqlBuilder();
  2425. $builder->select('*')->from('users');
  2426. $this->assertSame('select * from `users`', $builder->toSql());
  2427. }
  2428. public function testMySqlUpdateWrappingJson()
  2429. {
  2430. $grammar = new MySqlGrammar;
  2431. $processor = m::mock(Processor::class);
  2432. $connection = $this->createMock(ConnectionInterface::class);
  2433. $connection->expects($this->once())
  2434. ->method('update')
  2435. ->with(
  2436. 'update `users` set `name` = json_set(`name`, \'$."first_name"\', ?), `name` = json_set(`name`, \'$."last_name"\', ?) where `active` = ?',
  2437. ['John', 'Doe', 1]
  2438. );
  2439. $builder = new Builder($connection, $grammar, $processor);
  2440. $builder->from('users')->where('active', '=', 1)->update(['name->first_name' => 'John', 'name->last_name' => 'Doe']);
  2441. }
  2442. public function testMySqlUpdateWrappingNestedJson()
  2443. {
  2444. $grammar = new MySqlGrammar;
  2445. $processor = m::mock(Processor::class);
  2446. $connection = $this->createMock(ConnectionInterface::class);
  2447. $connection->expects($this->once())
  2448. ->method('update')
  2449. ->with(
  2450. 'update `users` set `meta` = json_set(`meta`, \'$."name"."first_name"\', ?), `meta` = json_set(`meta`, \'$."name"."last_name"\', ?) where `active` = ?',
  2451. ['John', 'Doe', 1]
  2452. );
  2453. $builder = new Builder($connection, $grammar, $processor);
  2454. $builder->from('users')->where('active', '=', 1)->update(['meta->name->first_name' => 'John', 'meta->name->last_name' => 'Doe']);
  2455. }
  2456. public function testMySqlUpdateWrappingJsonArray()
  2457. {
  2458. $grammar = new MySqlGrammar;
  2459. $processor = m::mock(Processor::class);
  2460. $connection = $this->createMock(ConnectionInterface::class);
  2461. $connection->expects($this->once())
  2462. ->method('update')
  2463. ->with(
  2464. 'update `users` set `options` = ?, `meta` = json_set(`meta`, \'$."tags"\', cast(? as json)), `group_id` = 45, `created_at` = ? where `active` = ?',
  2465. [
  2466. json_encode(['2fa' => false, 'presets' => ['laravel', 'vue']]),
  2467. json_encode(['white', 'large']),
  2468. new DateTime('2019-08-06'),
  2469. 1,
  2470. ]
  2471. );
  2472. $builder = new Builder($connection, $grammar, $processor);
  2473. $builder->from('users')->where('active', 1)->update([
  2474. 'options' => ['2fa' => false, 'presets' => ['laravel', 'vue']],
  2475. 'meta->tags' => ['white', 'large'],
  2476. 'group_id' => new Raw('45'),
  2477. 'created_at' => new DateTime('2019-08-06'),
  2478. ]);
  2479. }
  2480. public function testMySqlUpdateWithJsonPreparesBindingsCorrectly()
  2481. {
  2482. $grammar = new MySqlGrammar;
  2483. $processor = m::mock(Processor::class);
  2484. $connection = m::mock(ConnectionInterface::class);
  2485. $connection->shouldReceive('update')
  2486. ->once()
  2487. ->with(
  2488. 'update `users` set `options` = json_set(`options`, \'$."enable"\', false), `updated_at` = ? where `id` = ?',
  2489. ['2015-05-26 22:02:06', 0]
  2490. );
  2491. $builder = new Builder($connection, $grammar, $processor);
  2492. $builder->from('users')->where('id', '=', 0)->update(['options->enable' => false, 'updated_at' => '2015-05-26 22:02:06']);
  2493. $connection->shouldReceive('update')
  2494. ->once()
  2495. ->with(
  2496. 'update `users` set `options` = json_set(`options`, \'$."size"\', ?), `updated_at` = ? where `id` = ?',
  2497. [45, '2015-05-26 22:02:06', 0]
  2498. );
  2499. $builder = new Builder($connection, $grammar, $processor);
  2500. $builder->from('users')->where('id', '=', 0)->update(['options->size' => 45, 'updated_at' => '2015-05-26 22:02:06']);
  2501. $builder = $this->getMySqlBuilder();
  2502. $builder->getConnection()->shouldReceive('update')->once()->with('update `users` set `options` = json_set(`options`, \'$."size"\', ?)', [null]);
  2503. $builder->from('users')->update(['options->size' => null]);
  2504. $builder = $this->getMySqlBuilder();
  2505. $builder->getConnection()->shouldReceive('update')->once()->with('update `users` set `options` = json_set(`options`, \'$."size"\', 45)', []);
  2506. $builder->from('users')->update(['options->size' => new Raw('45')]);
  2507. }
  2508. public function testPostgresUpdateWrappingJson()
  2509. {
  2510. $builder = $this->getPostgresBuilder();
  2511. $builder->getConnection()->shouldReceive('update')
  2512. ->with('update "users" set "options" = jsonb_set("options"::jsonb, \'{"name","first_name"}\', ?)', ['"John"']);
  2513. $builder->from('users')->update(['users.options->name->first_name' => 'John']);
  2514. $builder = $this->getPostgresBuilder();
  2515. $builder->getConnection()->shouldReceive('update')
  2516. ->with('update "users" set "options" = jsonb_set("options"::jsonb, \'{"language"}\', \'null\')', []);
  2517. $builder->from('users')->update(['options->language' => new Raw("'null'")]);
  2518. }
  2519. public function testPostgresUpdateWrappingJsonArray()
  2520. {
  2521. $builder = $this->getPostgresBuilder();
  2522. $builder->getConnection()->shouldReceive('update')
  2523. ->with('update "users" set "options" = ?, "meta" = jsonb_set("meta"::jsonb, \'{"tags"}\', ?), "group_id" = 45, "created_at" = ?', [
  2524. json_encode(['2fa' => false, 'presets' => ['laravel', 'vue']]),
  2525. json_encode(['white', 'large']),
  2526. new DateTime('2019-08-06'),
  2527. ]);
  2528. $builder->from('users')->update([
  2529. 'options' => ['2fa' => false, 'presets' => ['laravel', 'vue']],
  2530. 'meta->tags' => ['white', 'large'],
  2531. 'group_id' => new Raw('45'),
  2532. 'created_at' => new DateTime('2019-08-06'),
  2533. ]);
  2534. }
  2535. public function testSQLiteUpdateWrappingJsonArray()
  2536. {
  2537. $builder = $this->getSQLiteBuilder();
  2538. $builder->getConnection()->shouldReceive('update')
  2539. ->with('update "users" set "options" = ?, "group_id" = 45, "created_at" = ?', [
  2540. json_encode(['2fa' => false, 'presets' => ['laravel', 'vue']]),
  2541. new DateTime('2019-08-06'),
  2542. ]);
  2543. $builder->from('users')->update([
  2544. 'options' => ['2fa' => false, 'presets' => ['laravel', 'vue']],
  2545. 'group_id' => new Raw('45'),
  2546. 'created_at' => new DateTime('2019-08-06'),
  2547. ]);
  2548. }
  2549. public function testSQLiteUpdateWrappingNestedJsonArray()
  2550. {
  2551. $builder = $this->getSQLiteBuilder();
  2552. $builder->getConnection()->shouldReceive('update')
  2553. ->with('update "users" set "group_id" = 45, "created_at" = ?, "options" = json_patch(ifnull("options", json(\'{}\')), json(?))', [
  2554. new DateTime('2019-08-06'),
  2555. json_encode(['name' => 'Taylor', 'security' => ['2fa' => false, 'presets' => ['laravel', 'vue']], 'sharing' => ['twitter' => 'username']]),
  2556. ]);
  2557. $builder->from('users')->update([
  2558. 'options->name' => 'Taylor',
  2559. 'group_id' => new Raw('45'),
  2560. 'options->security' => ['2fa' => false, 'presets' => ['laravel', 'vue']],
  2561. 'options->sharing->twitter' => 'username',
  2562. 'created_at' => new DateTime('2019-08-06'),
  2563. ]);
  2564. }
  2565. public function testMySqlWrappingJsonWithString()
  2566. {
  2567. $builder = $this->getMySqlBuilder();
  2568. $builder->select('*')->from('users')->where('items->sku', '=', 'foo-bar');
  2569. $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \'$."sku"\')) = ?', $builder->toSql());
  2570. $this->assertCount(1, $builder->getRawBindings()['where']);
  2571. $this->assertSame('foo-bar', $builder->getRawBindings()['where'][0]);
  2572. }
  2573. public function testMySqlWrappingJsonWithInteger()
  2574. {
  2575. $builder = $this->getMySqlBuilder();
  2576. $builder->select('*')->from('users')->where('items->price', '=', 1);
  2577. $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \'$."price"\')) = ?', $builder->toSql());
  2578. }
  2579. public function testMySqlWrappingJsonWithDouble()
  2580. {
  2581. $builder = $this->getMySqlBuilder();
  2582. $builder->select('*')->from('users')->where('items->price', '=', 1.5);
  2583. $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \'$."price"\')) = ?', $builder->toSql());
  2584. }
  2585. public function testMySqlWrappingJsonWithBoolean()
  2586. {
  2587. $builder = $this->getMySqlBuilder();
  2588. $builder->select('*')->from('users')->where('items->available', '=', true);
  2589. $this->assertSame('select * from `users` where json_extract(`items`, \'$."available"\') = true', $builder->toSql());
  2590. $builder = $this->getMySqlBuilder();
  2591. $builder->select('*')->from('users')->where(new Raw("items->'$.available'"), '=', true);
  2592. $this->assertSame("select * from `users` where items->'$.available' = true", $builder->toSql());
  2593. }
  2594. public function testMySqlWrappingJsonWithBooleanAndIntegerThatLooksLikeOne()
  2595. {
  2596. $builder = $this->getMySqlBuilder();
  2597. $builder->select('*')->from('users')->where('items->available', '=', true)->where('items->active', '=', false)->where('items->number_available', '=', 0);
  2598. $this->assertSame('select * from `users` where json_extract(`items`, \'$."available"\') = true and json_extract(`items`, \'$."active"\') = false and json_unquote(json_extract(`items`, \'$."number_available"\')) = ?', $builder->toSql());
  2599. }
  2600. public function testJsonPathEscaping()
  2601. {
  2602. $expectedWithJsonEscaped = <<<'SQL'
  2603. select json_unquote(json_extract(`json`, '$."''))#"'))
  2604. SQL;
  2605. $builder = $this->getMySqlBuilder();
  2606. $builder->select("json->'))#");
  2607. $this->assertEquals($expectedWithJsonEscaped, $builder->toSql());
  2608. $builder = $this->getMySqlBuilder();
  2609. $builder->select("json->\'))#");
  2610. $this->assertEquals($expectedWithJsonEscaped, $builder->toSql());
  2611. $builder = $this->getMySqlBuilder();
  2612. $builder->select("json->\\'))#");
  2613. $this->assertEquals($expectedWithJsonEscaped, $builder->toSql());
  2614. $builder = $this->getMySqlBuilder();
  2615. $builder->select("json->\\\'))#");
  2616. $this->assertEquals($expectedWithJsonEscaped, $builder->toSql());
  2617. }
  2618. public function testMySqlWrappingJson()
  2619. {
  2620. $builder = $this->getMySqlBuilder();
  2621. $builder->select('*')->from('users')->whereRaw('items->\'$."price"\' = 1');
  2622. $this->assertSame('select * from `users` where items->\'$."price"\' = 1', $builder->toSql());
  2623. $builder = $this->getMySqlBuilder();
  2624. $builder->select('items->price')->from('users')->where('users.items->price', '=', 1)->orderBy('items->price');
  2625. $this->assertSame('select json_unquote(json_extract(`items`, \'$."price"\')) from `users` where json_unquote(json_extract(`users`.`items`, \'$."price"\')) = ? order by json_unquote(json_extract(`items`, \'$."price"\')) asc', $builder->toSql());
  2626. $builder = $this->getMySqlBuilder();
  2627. $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1);
  2628. $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \'$."price"."in_usd"\')) = ?', $builder->toSql());
  2629. $builder = $this->getMySqlBuilder();
  2630. $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1)->where('items->age', '=', 2);
  2631. $this->assertSame('select * from `users` where json_unquote(json_extract(`items`, \'$."price"."in_usd"\')) = ? and json_unquote(json_extract(`items`, \'$."age"\')) = ?', $builder->toSql());
  2632. }
  2633. public function testPostgresWrappingJson()
  2634. {
  2635. $builder = $this->getPostgresBuilder();
  2636. $builder->select('items->price')->from('users')->where('users.items->price', '=', 1)->orderBy('items->price');
  2637. $this->assertSame('select "items"->>\'price\' from "users" where "users"."items"->>\'price\' = ? order by "items"->>\'price\' asc', $builder->toSql());
  2638. $builder = $this->getPostgresBuilder();
  2639. $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1);
  2640. $this->assertSame('select * from "users" where "items"->\'price\'->>\'in_usd\' = ?', $builder->toSql());
  2641. $builder = $this->getPostgresBuilder();
  2642. $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1)->where('items->age', '=', 2);
  2643. $this->assertSame('select * from "users" where "items"->\'price\'->>\'in_usd\' = ? and "items"->>\'age\' = ?', $builder->toSql());
  2644. $builder = $this->getPostgresBuilder();
  2645. $builder->select('*')->from('users')->where('items->prices->0', '=', 1)->where('items->age', '=', 2);
  2646. $this->assertSame('select * from "users" where "items"->\'prices\'->>0 = ? and "items"->>\'age\' = ?', $builder->toSql());
  2647. $builder = $this->getPostgresBuilder();
  2648. $builder->select('*')->from('users')->where('items->available', '=', true);
  2649. $this->assertSame('select * from "users" where ("items"->\'available\')::jsonb = \'true\'::jsonb', $builder->toSql());
  2650. }
  2651. public function testSqlServerWrappingJson()
  2652. {
  2653. $builder = $this->getSqlServerBuilder();
  2654. $builder->select('items->price')->from('users')->where('users.items->price', '=', 1)->orderBy('items->price');
  2655. $this->assertSame('select json_value([items], \'$."price"\') from [users] where json_value([users].[items], \'$."price"\') = ? order by json_value([items], \'$."price"\') asc', $builder->toSql());
  2656. $builder = $this->getSqlServerBuilder();
  2657. $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1);
  2658. $this->assertSame('select * from [users] where json_value([items], \'$."price"."in_usd"\') = ?', $builder->toSql());
  2659. $builder = $this->getSqlServerBuilder();
  2660. $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1)->where('items->age', '=', 2);
  2661. $this->assertSame('select * from [users] where json_value([items], \'$."price"."in_usd"\') = ? and json_value([items], \'$."age"\') = ?', $builder->toSql());
  2662. $builder = $this->getSqlServerBuilder();
  2663. $builder->select('*')->from('users')->where('items->available', '=', true);
  2664. $this->assertSame('select * from [users] where json_value([items], \'$."available"\') = \'true\'', $builder->toSql());
  2665. }
  2666. public function testSqliteWrappingJson()
  2667. {
  2668. $builder = $this->getSQLiteBuilder();
  2669. $builder->select('items->price')->from('users')->where('users.items->price', '=', 1)->orderBy('items->price');
  2670. $this->assertSame('select json_extract("items", \'$."price"\') from "users" where json_extract("users"."items", \'$."price"\') = ? order by json_extract("items", \'$."price"\') asc', $builder->toSql());
  2671. $builder = $this->getSQLiteBuilder();
  2672. $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1);
  2673. $this->assertSame('select * from "users" where json_extract("items", \'$."price"."in_usd"\') = ?', $builder->toSql());
  2674. $builder = $this->getSQLiteBuilder();
  2675. $builder->select('*')->from('users')->where('items->price->in_usd', '=', 1)->where('items->age', '=', 2);
  2676. $this->assertSame('select * from "users" where json_extract("items", \'$."price"."in_usd"\') = ? and json_extract("items", \'$."age"\') = ?', $builder->toSql());
  2677. $builder = $this->getSQLiteBuilder();
  2678. $builder->select('*')->from('users')->where('items->available', '=', true);
  2679. $this->assertSame('select * from "users" where json_extract("items", \'$."available"\') = true', $builder->toSql());
  2680. }
  2681. public function testSQLiteOrderBy()
  2682. {
  2683. $builder = $this->getSQLiteBuilder();
  2684. $builder->select('*')->from('users')->orderBy('email', 'desc');
  2685. $this->assertSame('select * from "users" order by "email" desc', $builder->toSql());
  2686. }
  2687. public function testSqlServerLimitsAndOffsets()
  2688. {
  2689. $builder = $this->getSqlServerBuilder();
  2690. $builder->select('*')->from('users')->take(10);
  2691. $this->assertSame('select top 10 * from [users]', $builder->toSql());
  2692. $builder = $this->getSqlServerBuilder();
  2693. $builder->select('*')->from('users')->skip(10);
  2694. $this->assertSame('select * from (select *, row_number() over (order by (select 0)) as row_num from [users]) as temp_table where row_num >= 11 order by row_num', $builder->toSql());
  2695. $builder = $this->getSqlServerBuilder();
  2696. $builder->select('*')->from('users')->skip(10)->take(10);
  2697. $this->assertSame('select * from (select *, row_number() over (order by (select 0)) as row_num from [users]) as temp_table where row_num between 11 and 20 order by row_num', $builder->toSql());
  2698. $builder = $this->getSqlServerBuilder();
  2699. $builder->select('*')->from('users')->skip(11)->take(10)->orderBy('email', 'desc');
  2700. $this->assertSame('select * from [users] order by [email] desc offset 11 rows fetch next 10 rows only', $builder->toSql());
  2701. $builder = $this->getSqlServerBuilder();
  2702. $subQueryBuilder = $this->getSqlServerBuilder();
  2703. $subQuery = function ($query) {
  2704. return $query->select('created_at')->from('logins')->where('users.name', 'nameBinding')->whereColumn('user_id', 'users.id')->limit(1);
  2705. };
  2706. $builder->select('*')->from('users')->where('email', 'emailBinding')->orderBy($subQuery)->skip(10)->take(10);
  2707. $this->assertSame('select * from [users] where [email] = ? order by (select top 1 [created_at] from [logins] where [users].[name] = ? and [user_id] = [users].[id]) asc offset 10 rows fetch next 10 rows only', $builder->toSql());
  2708. $this->assertEquals(['emailBinding', 'nameBinding'], $builder->getBindings());
  2709. $builder = $this->getSqlServerBuilder();
  2710. $builder->select('*')->from('users')->take('foo');
  2711. $this->assertSame('select * from [users]', $builder->toSql());
  2712. $builder = $this->getSqlServerBuilder();
  2713. $builder->select('*')->from('users')->take('foo')->offset('bar');
  2714. $this->assertSame('select * from [users]', $builder->toSql());
  2715. $builder = $this->getSqlServerBuilder();
  2716. $builder->select('*')->from('users')->offset('bar');
  2717. $this->assertSame('select * from [users]', $builder->toSql());
  2718. }
  2719. public function testMySqlSoundsLikeOperator()
  2720. {
  2721. $builder = $this->getMySqlBuilder();
  2722. $builder->select('*')->from('users')->where('name', 'sounds like', 'John Doe');
  2723. $this->assertSame('select * from `users` where `name` sounds like ?', $builder->toSql());
  2724. $this->assertEquals(['John Doe'], $builder->getBindings());
  2725. }
  2726. public function testBitwiseOperators()
  2727. {
  2728. $builder = $this->getBuilder();
  2729. $builder->select('*')->from('users')->where('bar', '&', 1);
  2730. $this->assertSame('select * from "users" where "bar" & ?', $builder->toSql());
  2731. $builder = $this->getPostgresBuilder();
  2732. $builder->select('*')->from('users')->where('bar', '#', 1);
  2733. $this->assertSame('select * from "users" where ("bar" # ?)::bool', $builder->toSql());
  2734. $builder = $this->getPostgresBuilder();
  2735. $builder->select('*')->from('users')->where('range', '>>', '[2022-01-08 00:00:00,2022-01-09 00:00:00)');
  2736. $this->assertSame('select * from "users" where ("range" >> ?)::bool', $builder->toSql());
  2737. $builder = $this->getSqlServerBuilder();
  2738. $builder->select('*')->from('users')->where('bar', '&', 1);
  2739. $this->assertSame('select * from [users] where ([bar] & ?) != 0', $builder->toSql());
  2740. $builder = $this->getBuilder();
  2741. $builder->select('*')->from('users')->having('bar', '&', 1);
  2742. $this->assertSame('select * from "users" having "bar" & ?', $builder->toSql());
  2743. $builder = $this->getPostgresBuilder();
  2744. $builder->select('*')->from('users')->having('bar', '#', 1);
  2745. $this->assertSame('select * from "users" having ("bar" # ?)::bool', $builder->toSql());
  2746. $builder = $this->getPostgresBuilder();
  2747. $builder->select('*')->from('users')->having('range', '>>', '[2022-01-08 00:00:00,2022-01-09 00:00:00)');
  2748. $this->assertSame('select * from "users" having ("range" >> ?)::bool', $builder->toSql());
  2749. $builder = $this->getSqlServerBuilder();
  2750. $builder->select('*')->from('users')->having('bar', '&', 1);
  2751. $this->assertSame('select * from [users] having ([bar] & ?) != 0', $builder->toSql());
  2752. }
  2753. public function testMergeWheresCanMergeWheresAndBindings()
  2754. {
  2755. $builder = $this->getBuilder();
  2756. $builder->wheres = ['foo'];
  2757. $builder->mergeWheres(['wheres'], [12 => 'foo', 13 => 'bar']);
  2758. $this->assertEquals(['foo', 'wheres'], $builder->wheres);
  2759. $this->assertEquals(['foo', 'bar'], $builder->getBindings());
  2760. }
  2761. public function testProvidingNullWithOperatorsBuildsCorrectly()
  2762. {
  2763. $builder = $this->getBuilder();
  2764. $builder->select('*')->from('users')->where('foo', null);
  2765. $this->assertSame('select * from "users" where "foo" is null', $builder->toSql());
  2766. $builder = $this->getBuilder();
  2767. $builder->select('*')->from('users')->where('foo', '=', null);
  2768. $this->assertSame('select * from "users" where "foo" is null', $builder->toSql());
  2769. $builder = $this->getBuilder();
  2770. $builder->select('*')->from('users')->where('foo', '!=', null);
  2771. $this->assertSame('select * from "users" where "foo" is not null', $builder->toSql());
  2772. $builder = $this->getBuilder();
  2773. $builder->select('*')->from('users')->where('foo', '<>', null);
  2774. $this->assertSame('select * from "users" where "foo" is not null', $builder->toSql());
  2775. }
  2776. public function testDynamicWhere()
  2777. {
  2778. $method = 'whereFooBarAndBazOrQux';
  2779. $parameters = ['corge', 'waldo', 'fred'];
  2780. $builder = m::mock(Builder::class)->makePartial();
  2781. $builder->shouldReceive('where')->with('foo_bar', '=', $parameters[0], 'and')->once()->andReturnSelf();
  2782. $builder->shouldReceive('where')->with('baz', '=', $parameters[1], 'and')->once()->andReturnSelf();
  2783. $builder->shouldReceive('where')->with('qux', '=', $parameters[2], 'or')->once()->andReturnSelf();
  2784. $this->assertEquals($builder, $builder->dynamicWhere($method, $parameters));
  2785. }
  2786. public function testDynamicWhereIsNotGreedy()
  2787. {
  2788. $method = 'whereIosVersionAndAndroidVersionOrOrientation';
  2789. $parameters = ['6.1', '4.2', 'Vertical'];
  2790. $builder = m::mock(Builder::class)->makePartial();
  2791. $builder->shouldReceive('where')->with('ios_version', '=', '6.1', 'and')->once()->andReturnSelf();
  2792. $builder->shouldReceive('where')->with('android_version', '=', '4.2', 'and')->once()->andReturnSelf();
  2793. $builder->shouldReceive('where')->with('orientation', '=', 'Vertical', 'or')->once()->andReturnSelf();
  2794. $builder->dynamicWhere($method, $parameters);
  2795. }
  2796. public function testCallTriggersDynamicWhere()
  2797. {
  2798. $builder = $this->getBuilder();
  2799. $this->assertEquals($builder, $builder->whereFooAndBar('baz', 'qux'));
  2800. $this->assertCount(2, $builder->wheres);
  2801. }
  2802. public function testBuilderThrowsExpectedExceptionWithUndefinedMethod()
  2803. {
  2804. $this->expectException(BadMethodCallException::class);
  2805. $builder = $this->getBuilder();
  2806. $builder->getConnection()->shouldReceive('select');
  2807. $builder->getProcessor()->shouldReceive('processSelect')->andReturn([]);
  2808. $builder->noValidMethodHere();
  2809. }
  2810. public function testMySqlLock()
  2811. {
  2812. $builder = $this->getMySqlBuilder();
  2813. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock();
  2814. $this->assertSame('select * from `foo` where `bar` = ? for update', $builder->toSql());
  2815. $this->assertEquals(['baz'], $builder->getBindings());
  2816. $builder = $this->getMySqlBuilder();
  2817. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false);
  2818. $this->assertSame('select * from `foo` where `bar` = ? lock in share mode', $builder->toSql());
  2819. $this->assertEquals(['baz'], $builder->getBindings());
  2820. $builder = $this->getMySqlBuilder();
  2821. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock('lock in share mode');
  2822. $this->assertSame('select * from `foo` where `bar` = ? lock in share mode', $builder->toSql());
  2823. $this->assertEquals(['baz'], $builder->getBindings());
  2824. }
  2825. public function testPostgresLock()
  2826. {
  2827. $builder = $this->getPostgresBuilder();
  2828. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock();
  2829. $this->assertSame('select * from "foo" where "bar" = ? for update', $builder->toSql());
  2830. $this->assertEquals(['baz'], $builder->getBindings());
  2831. $builder = $this->getPostgresBuilder();
  2832. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false);
  2833. $this->assertSame('select * from "foo" where "bar" = ? for share', $builder->toSql());
  2834. $this->assertEquals(['baz'], $builder->getBindings());
  2835. $builder = $this->getPostgresBuilder();
  2836. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock('for key share');
  2837. $this->assertSame('select * from "foo" where "bar" = ? for key share', $builder->toSql());
  2838. $this->assertEquals(['baz'], $builder->getBindings());
  2839. }
  2840. public function testSqlServerLock()
  2841. {
  2842. $builder = $this->getSqlServerBuilder();
  2843. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock();
  2844. $this->assertSame('select * from [foo] with(rowlock,updlock,holdlock) where [bar] = ?', $builder->toSql());
  2845. $this->assertEquals(['baz'], $builder->getBindings());
  2846. $builder = $this->getSqlServerBuilder();
  2847. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false);
  2848. $this->assertSame('select * from [foo] with(rowlock,holdlock) where [bar] = ?', $builder->toSql());
  2849. $this->assertEquals(['baz'], $builder->getBindings());
  2850. $builder = $this->getSqlServerBuilder();
  2851. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock('with(holdlock)');
  2852. $this->assertSame('select * from [foo] with(holdlock) where [bar] = ?', $builder->toSql());
  2853. $this->assertEquals(['baz'], $builder->getBindings());
  2854. }
  2855. public function testSelectWithLockUsesWritePdo()
  2856. {
  2857. $builder = $this->getMySqlBuilderWithProcessor();
  2858. $builder->getConnection()->shouldReceive('select')->once()
  2859. ->with(m::any(), m::any(), false);
  2860. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock()->get();
  2861. $builder = $this->getMySqlBuilderWithProcessor();
  2862. $builder->getConnection()->shouldReceive('select')->once()
  2863. ->with(m::any(), m::any(), false);
  2864. $builder->select('*')->from('foo')->where('bar', '=', 'baz')->lock(false)->get();
  2865. }
  2866. public function testBindingOrder()
  2867. {
  2868. $expectedSql = 'select * from "users" inner join "othertable" on "bar" = ? where "registered" = ? group by "city" having "population" > ? order by match ("foo") against(?)';
  2869. $expectedBindings = ['foo', 1, 3, 'bar'];
  2870. $builder = $this->getBuilder();
  2871. $builder->select('*')->from('users')->join('othertable', function ($join) {
  2872. $join->where('bar', '=', 'foo');
  2873. })->where('registered', 1)->groupBy('city')->having('population', '>', 3)->orderByRaw('match ("foo") against(?)', ['bar']);
  2874. $this->assertEquals($expectedSql, $builder->toSql());
  2875. $this->assertEquals($expectedBindings, $builder->getBindings());
  2876. // order of statements reversed
  2877. $builder = $this->getBuilder();
  2878. $builder->select('*')->from('users')->orderByRaw('match ("foo") against(?)', ['bar'])->having('population', '>', 3)->groupBy('city')->where('registered', 1)->join('othertable', function ($join) {
  2879. $join->where('bar', '=', 'foo');
  2880. });
  2881. $this->assertEquals($expectedSql, $builder->toSql());
  2882. $this->assertEquals($expectedBindings, $builder->getBindings());
  2883. }
  2884. public function testAddBindingWithArrayMergesBindings()
  2885. {
  2886. $builder = $this->getBuilder();
  2887. $builder->addBinding(['foo', 'bar']);
  2888. $builder->addBinding(['baz']);
  2889. $this->assertEquals(['foo', 'bar', 'baz'], $builder->getBindings());
  2890. }
  2891. public function testAddBindingWithArrayMergesBindingsInCorrectOrder()
  2892. {
  2893. $builder = $this->getBuilder();
  2894. $builder->addBinding(['bar', 'baz'], 'having');
  2895. $builder->addBinding(['foo'], 'where');
  2896. $this->assertEquals(['foo', 'bar', 'baz'], $builder->getBindings());
  2897. }
  2898. public function testMergeBuilders()
  2899. {
  2900. $builder = $this->getBuilder();
  2901. $builder->addBinding(['foo', 'bar']);
  2902. $otherBuilder = $this->getBuilder();
  2903. $otherBuilder->addBinding(['baz']);
  2904. $builder->mergeBindings($otherBuilder);
  2905. $this->assertEquals(['foo', 'bar', 'baz'], $builder->getBindings());
  2906. }
  2907. public function testMergeBuildersBindingOrder()
  2908. {
  2909. $builder = $this->getBuilder();
  2910. $builder->addBinding('foo', 'where');
  2911. $builder->addBinding('baz', 'having');
  2912. $otherBuilder = $this->getBuilder();
  2913. $otherBuilder->addBinding('bar', 'where');
  2914. $builder->mergeBindings($otherBuilder);
  2915. $this->assertEquals(['foo', 'bar', 'baz'], $builder->getBindings());
  2916. }
  2917. public function testSubSelect()
  2918. {
  2919. $expectedSql = 'select "foo", "bar", (select "baz" from "two" where "subkey" = ?) as "sub" from "one" where "key" = ?';
  2920. $expectedBindings = ['subval', 'val'];
  2921. $builder = $this->getPostgresBuilder();
  2922. $builder->from('one')->select(['foo', 'bar'])->where('key', '=', 'val');
  2923. $builder->selectSub(function ($query) {
  2924. $query->from('two')->select('baz')->where('subkey', '=', 'subval');
  2925. }, 'sub');
  2926. $this->assertEquals($expectedSql, $builder->toSql());
  2927. $this->assertEquals($expectedBindings, $builder->getBindings());
  2928. $builder = $this->getPostgresBuilder();
  2929. $builder->from('one')->select(['foo', 'bar'])->where('key', '=', 'val');
  2930. $subBuilder = $this->getPostgresBuilder();
  2931. $subBuilder->from('two')->select('baz')->where('subkey', '=', 'subval');
  2932. $builder->selectSub($subBuilder, 'sub');
  2933. $this->assertEquals($expectedSql, $builder->toSql());
  2934. $this->assertEquals($expectedBindings, $builder->getBindings());
  2935. $this->expectException(InvalidArgumentException::class);
  2936. $builder = $this->getPostgresBuilder();
  2937. $builder->selectSub(['foo'], 'sub');
  2938. }
  2939. public function testSubSelectResetBindings()
  2940. {
  2941. $builder = $this->getPostgresBuilder();
  2942. $builder->from('one')->selectSub(function ($query) {
  2943. $query->from('two')->select('baz')->where('subkey', '=', 'subval');
  2944. }, 'sub');
  2945. $this->assertSame('select (select "baz" from "two" where "subkey" = ?) as "sub" from "one"', $builder->toSql());
  2946. $this->assertEquals(['subval'], $builder->getBindings());
  2947. $builder->select('*');
  2948. $this->assertSame('select * from "one"', $builder->toSql());
  2949. $this->assertEquals([], $builder->getBindings());
  2950. }
  2951. public function testSqlServerWhereDate()
  2952. {
  2953. $builder = $this->getSqlServerBuilder();
  2954. $builder->select('*')->from('users')->whereDate('created_at', '=', '2015-09-23');
  2955. $this->assertSame('select * from [users] where cast([created_at] as date) = ?', $builder->toSql());
  2956. $this->assertEquals([0 => '2015-09-23'], $builder->getBindings());
  2957. }
  2958. public function testUppercaseLeadingBooleansAreRemoved()
  2959. {
  2960. $builder = $this->getBuilder();
  2961. $builder->select('*')->from('users')->where('name', '=', 'Taylor', 'AND');
  2962. $this->assertSame('select * from "users" where "name" = ?', $builder->toSql());
  2963. }
  2964. public function testLowercaseLeadingBooleansAreRemoved()
  2965. {
  2966. $builder = $this->getBuilder();
  2967. $builder->select('*')->from('users')->where('name', '=', 'Taylor', 'and');
  2968. $this->assertSame('select * from "users" where "name" = ?', $builder->toSql());
  2969. }
  2970. public function testCaseInsensitiveLeadingBooleansAreRemoved()
  2971. {
  2972. $builder = $this->getBuilder();
  2973. $builder->select('*')->from('users')->where('name', '=', 'Taylor', 'And');
  2974. $this->assertSame('select * from "users" where "name" = ?', $builder->toSql());
  2975. }
  2976. public function testTableValuedFunctionAsTableInSqlServer()
  2977. {
  2978. $builder = $this->getSqlServerBuilder();
  2979. $builder->select('*')->from('users()');
  2980. $this->assertSame('select * from [users]()', $builder->toSql());
  2981. $builder = $this->getSqlServerBuilder();
  2982. $builder->select('*')->from('users(1,2)');
  2983. $this->assertSame('select * from [users](1,2)', $builder->toSql());
  2984. }
  2985. public function testChunkWithLastChunkComplete()
  2986. {
  2987. $builder = $this->getMockQueryBuilder();
  2988. $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];
  2989. $chunk1 = collect(['foo1', 'foo2']);
  2990. $chunk2 = collect(['foo3', 'foo4']);
  2991. $chunk3 = collect([]);
  2992. $builder->shouldReceive('forPage')->once()->with(1, 2)->andReturnSelf();
  2993. $builder->shouldReceive('forPage')->once()->with(2, 2)->andReturnSelf();
  2994. $builder->shouldReceive('forPage')->once()->with(3, 2)->andReturnSelf();
  2995. $builder->shouldReceive('get')->times(3)->andReturn($chunk1, $chunk2, $chunk3);
  2996. $callbackAssertor = m::mock(stdClass::class);
  2997. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);
  2998. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);
  2999. $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk3);
  3000. $builder->chunk(2, function ($results) use ($callbackAssertor) {
  3001. $callbackAssertor->doSomething($results);
  3002. });
  3003. }
  3004. public function testChunkWithLastChunkPartial()
  3005. {
  3006. $builder = $this->getMockQueryBuilder();
  3007. $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];
  3008. $chunk1 = collect(['foo1', 'foo2']);
  3009. $chunk2 = collect(['foo3']);
  3010. $builder->shouldReceive('forPage')->once()->with(1, 2)->andReturnSelf();
  3011. $builder->shouldReceive('forPage')->once()->with(2, 2)->andReturnSelf();
  3012. $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);
  3013. $callbackAssertor = m::mock(stdClass::class);
  3014. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);
  3015. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);
  3016. $builder->chunk(2, function ($results) use ($callbackAssertor) {
  3017. $callbackAssertor->doSomething($results);
  3018. });
  3019. }
  3020. public function testChunkCanBeStoppedByReturningFalse()
  3021. {
  3022. $builder = $this->getMockQueryBuilder();
  3023. $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];
  3024. $chunk1 = collect(['foo1', 'foo2']);
  3025. $chunk2 = collect(['foo3']);
  3026. $builder->shouldReceive('forPage')->once()->with(1, 2)->andReturnSelf();
  3027. $builder->shouldReceive('forPage')->never()->with(2, 2);
  3028. $builder->shouldReceive('get')->times(1)->andReturn($chunk1);
  3029. $callbackAssertor = m::mock(stdClass::class);
  3030. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);
  3031. $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk2);
  3032. $builder->chunk(2, function ($results) use ($callbackAssertor) {
  3033. $callbackAssertor->doSomething($results);
  3034. return false;
  3035. });
  3036. }
  3037. public function testChunkWithCountZero()
  3038. {
  3039. $builder = $this->getMockQueryBuilder();
  3040. $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];
  3041. $chunk = collect([]);
  3042. $builder->shouldReceive('forPage')->once()->with(1, 0)->andReturnSelf();
  3043. $builder->shouldReceive('get')->times(1)->andReturn($chunk);
  3044. $callbackAssertor = m::mock(stdClass::class);
  3045. $callbackAssertor->shouldReceive('doSomething')->never();
  3046. $builder->chunk(0, function ($results) use ($callbackAssertor) {
  3047. $callbackAssertor->doSomething($results);
  3048. });
  3049. }
  3050. public function testChunkPaginatesUsingIdWithLastChunkComplete()
  3051. {
  3052. $builder = $this->getMockQueryBuilder();
  3053. $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];
  3054. $chunk1 = collect([(object) ['someIdField' => 1], (object) ['someIdField' => 2]]);
  3055. $chunk2 = collect([(object) ['someIdField' => 10], (object) ['someIdField' => 11]]);
  3056. $chunk3 = collect([]);
  3057. $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();
  3058. $builder->shouldReceive('forPageAfterId')->once()->with(2, 2, 'someIdField')->andReturnSelf();
  3059. $builder->shouldReceive('forPageAfterId')->once()->with(2, 11, 'someIdField')->andReturnSelf();
  3060. $builder->shouldReceive('get')->times(3)->andReturn($chunk1, $chunk2, $chunk3);
  3061. $callbackAssertor = m::mock(stdClass::class);
  3062. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);
  3063. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);
  3064. $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk3);
  3065. $builder->chunkById(2, function ($results) use ($callbackAssertor) {
  3066. $callbackAssertor->doSomething($results);
  3067. }, 'someIdField');
  3068. }
  3069. public function testChunkPaginatesUsingIdWithLastChunkPartial()
  3070. {
  3071. $builder = $this->getMockQueryBuilder();
  3072. $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];
  3073. $chunk1 = collect([(object) ['someIdField' => 1], (object) ['someIdField' => 2]]);
  3074. $chunk2 = collect([(object) ['someIdField' => 10]]);
  3075. $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'someIdField')->andReturnSelf();
  3076. $builder->shouldReceive('forPageAfterId')->once()->with(2, 2, 'someIdField')->andReturnSelf();
  3077. $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);
  3078. $callbackAssertor = m::mock(stdClass::class);
  3079. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);
  3080. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk2);
  3081. $builder->chunkById(2, function ($results) use ($callbackAssertor) {
  3082. $callbackAssertor->doSomething($results);
  3083. }, 'someIdField');
  3084. }
  3085. public function testChunkPaginatesUsingIdWithCountZero()
  3086. {
  3087. $builder = $this->getMockQueryBuilder();
  3088. $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];
  3089. $chunk = collect([]);
  3090. $builder->shouldReceive('forPageAfterId')->once()->with(0, 0, 'someIdField')->andReturnSelf();
  3091. $builder->shouldReceive('get')->times(1)->andReturn($chunk);
  3092. $callbackAssertor = m::mock(stdClass::class);
  3093. $callbackAssertor->shouldReceive('doSomething')->never();
  3094. $builder->chunkById(0, function ($results) use ($callbackAssertor) {
  3095. $callbackAssertor->doSomething($results);
  3096. }, 'someIdField');
  3097. }
  3098. public function testChunkPaginatesUsingIdWithAlias()
  3099. {
  3100. $builder = $this->getMockQueryBuilder();
  3101. $builder->orders[] = ['column' => 'foobar', 'direction' => 'asc'];
  3102. $chunk1 = collect([(object) ['table_id' => 1], (object) ['table_id' => 10]]);
  3103. $chunk2 = collect([]);
  3104. $builder->shouldReceive('forPageAfterId')->once()->with(2, 0, 'table.id')->andReturnSelf();
  3105. $builder->shouldReceive('forPageAfterId')->once()->with(2, 10, 'table.id')->andReturnSelf();
  3106. $builder->shouldReceive('get')->times(2)->andReturn($chunk1, $chunk2);
  3107. $callbackAssertor = m::mock(stdClass::class);
  3108. $callbackAssertor->shouldReceive('doSomething')->once()->with($chunk1);
  3109. $callbackAssertor->shouldReceive('doSomething')->never()->with($chunk2);
  3110. $builder->chunkById(2, function ($results) use ($callbackAssertor) {
  3111. $callbackAssertor->doSomething($results);
  3112. }, 'table.id', 'table_id');
  3113. }
  3114. public function testPaginate()
  3115. {
  3116. $perPage = 16;
  3117. $columns = ['test'];
  3118. $pageName = 'page-name';
  3119. $page = 1;
  3120. $builder = $this->getMockQueryBuilder();
  3121. $path = 'http://foo.bar?page=3';
  3122. $results = collect([['test' => 'foo'], ['test' => 'bar']]);
  3123. $builder->shouldReceive('getCountForPagination')->once()->andReturn(2);
  3124. $builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturnSelf();
  3125. $builder->shouldReceive('get')->once()->andReturn($results);
  3126. Paginator::currentPathResolver(function () use ($path) {
  3127. return $path;
  3128. });
  3129. $result = $builder->paginate($perPage, $columns, $pageName, $page);
  3130. $this->assertEquals(new LengthAwarePaginator($results, 2, $perPage, $page, [
  3131. 'path' => $path,
  3132. 'pageName' => $pageName,
  3133. ]), $result);
  3134. }
  3135. public function testPaginateWithDefaultArguments()
  3136. {
  3137. $perPage = 15;
  3138. $pageName = 'page';
  3139. $page = 1;
  3140. $builder = $this->getMockQueryBuilder();
  3141. $path = 'http://foo.bar?page=3';
  3142. $results = collect([['test' => 'foo'], ['test' => 'bar']]);
  3143. $builder->shouldReceive('getCountForPagination')->once()->andReturn(2);
  3144. $builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturnSelf();
  3145. $builder->shouldReceive('get')->once()->andReturn($results);
  3146. Paginator::currentPageResolver(function () {
  3147. return 1;
  3148. });
  3149. Paginator::currentPathResolver(function () use ($path) {
  3150. return $path;
  3151. });
  3152. $result = $builder->paginate();
  3153. $this->assertEquals(new LengthAwarePaginator($results, 2, $perPage, $page, [
  3154. 'path' => $path,
  3155. 'pageName' => $pageName,
  3156. ]), $result);
  3157. }
  3158. public function testPaginateWhenNoResults()
  3159. {
  3160. $perPage = 15;
  3161. $pageName = 'page';
  3162. $page = 1;
  3163. $builder = $this->getMockQueryBuilder();
  3164. $path = 'http://foo.bar?page=3';
  3165. $results = [];
  3166. $builder->shouldReceive('getCountForPagination')->once()->andReturn(0);
  3167. $builder->shouldNotReceive('forPage');
  3168. $builder->shouldNotReceive('get');
  3169. Paginator::currentPageResolver(function () {
  3170. return 1;
  3171. });
  3172. Paginator::currentPathResolver(function () use ($path) {
  3173. return $path;
  3174. });
  3175. $result = $builder->paginate();
  3176. $this->assertEquals(new LengthAwarePaginator($results, 0, $perPage, $page, [
  3177. 'path' => $path,
  3178. 'pageName' => $pageName,
  3179. ]), $result);
  3180. }
  3181. public function testPaginateWithSpecificColumns()
  3182. {
  3183. $perPage = 16;
  3184. $columns = ['id', 'name'];
  3185. $pageName = 'page-name';
  3186. $page = 1;
  3187. $builder = $this->getMockQueryBuilder();
  3188. $path = 'http://foo.bar?page=3';
  3189. $results = collect([['id' => 3, 'name' => 'Taylor'], ['id' => 5, 'name' => 'Mohamed']]);
  3190. $builder->shouldReceive('getCountForPagination')->once()->andReturn(2);
  3191. $builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturnSelf();
  3192. $builder->shouldReceive('get')->once()->andReturn($results);
  3193. Paginator::currentPathResolver(function () use ($path) {
  3194. return $path;
  3195. });
  3196. $result = $builder->paginate($perPage, $columns, $pageName, $page);
  3197. $this->assertEquals(new LengthAwarePaginator($results, 2, $perPage, $page, [
  3198. 'path' => $path,
  3199. 'pageName' => $pageName,
  3200. ]), $result);
  3201. }
  3202. public function testCursorPaginate()
  3203. {
  3204. $perPage = 16;
  3205. $columns = ['test'];
  3206. $cursorName = 'cursor-name';
  3207. $cursor = new Cursor(['test' => 'bar']);
  3208. $builder = $this->getMockQueryBuilder();
  3209. $builder->from('foobar')->orderBy('test');
  3210. $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {
  3211. return new Builder($builder->connection, $builder->grammar, $builder->processor);
  3212. });
  3213. $path = 'http://foo.bar?cursor='.$cursor->encode();
  3214. $results = collect([['test' => 'foo'], ['test' => 'bar']]);
  3215. $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {
  3216. $this->assertEquals(
  3217. 'select * from "foobar" where ("test" > ?) order by "test" asc limit 17',
  3218. $builder->toSql());
  3219. $this->assertEquals(['bar'], $builder->bindings['where']);
  3220. return $results;
  3221. });
  3222. Paginator::currentPathResolver(function () use ($path) {
  3223. return $path;
  3224. });
  3225. $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);
  3226. $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [
  3227. 'path' => $path,
  3228. 'cursorName' => $cursorName,
  3229. 'parameters' => ['test'],
  3230. ]), $result);
  3231. }
  3232. public function testCursorPaginateMultipleOrderColumns()
  3233. {
  3234. $perPage = 16;
  3235. $columns = ['test', 'another'];
  3236. $cursorName = 'cursor-name';
  3237. $cursor = new Cursor(['test' => 'bar', 'another' => 'foo']);
  3238. $builder = $this->getMockQueryBuilder();
  3239. $builder->from('foobar')->orderBy('test')->orderBy('another');
  3240. $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {
  3241. return new Builder($builder->connection, $builder->grammar, $builder->processor);
  3242. });
  3243. $path = 'http://foo.bar?cursor='.$cursor->encode();
  3244. $results = collect([['test' => 'foo', 'another' => 1], ['test' => 'bar', 'another' => 2]]);
  3245. $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {
  3246. $this->assertEquals(
  3247. 'select * from "foobar" where ("test" > ? or ("test" = ? and ("another" > ?))) order by "test" asc, "another" asc limit 17',
  3248. $builder->toSql()
  3249. );
  3250. $this->assertEquals(['bar', 'bar', 'foo'], $builder->bindings['where']);
  3251. return $results;
  3252. });
  3253. Paginator::currentPathResolver(function () use ($path) {
  3254. return $path;
  3255. });
  3256. $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);
  3257. $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [
  3258. 'path' => $path,
  3259. 'cursorName' => $cursorName,
  3260. 'parameters' => ['test', 'another'],
  3261. ]), $result);
  3262. }
  3263. public function testCursorPaginateWithDefaultArguments()
  3264. {
  3265. $perPage = 15;
  3266. $cursorName = 'cursor';
  3267. $cursor = new Cursor(['test' => 'bar']);
  3268. $builder = $this->getMockQueryBuilder();
  3269. $builder->from('foobar')->orderBy('test');
  3270. $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {
  3271. return new Builder($builder->connection, $builder->grammar, $builder->processor);
  3272. });
  3273. $path = 'http://foo.bar?cursor='.$cursor->encode();
  3274. $results = collect([['test' => 'foo'], ['test' => 'bar']]);
  3275. $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {
  3276. $this->assertEquals(
  3277. 'select * from "foobar" where ("test" > ?) order by "test" asc limit 16',
  3278. $builder->toSql());
  3279. $this->assertEquals(['bar'], $builder->bindings['where']);
  3280. return $results;
  3281. });
  3282. CursorPaginator::currentCursorResolver(function () use ($cursor) {
  3283. return $cursor;
  3284. });
  3285. Paginator::currentPathResolver(function () use ($path) {
  3286. return $path;
  3287. });
  3288. $result = $builder->cursorPaginate();
  3289. $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [
  3290. 'path' => $path,
  3291. 'cursorName' => $cursorName,
  3292. 'parameters' => ['test'],
  3293. ]), $result);
  3294. }
  3295. public function testCursorPaginateWhenNoResults()
  3296. {
  3297. $perPage = 15;
  3298. $cursorName = 'cursor';
  3299. $builder = $this->getMockQueryBuilder()->orderBy('test');
  3300. $path = 'http://foo.bar?cursor=3';
  3301. $results = [];
  3302. $builder->shouldReceive('get')->once()->andReturn($results);
  3303. CursorPaginator::currentCursorResolver(function () {
  3304. return null;
  3305. });
  3306. Paginator::currentPathResolver(function () use ($path) {
  3307. return $path;
  3308. });
  3309. $result = $builder->cursorPaginate();
  3310. $this->assertEquals(new CursorPaginator($results, $perPage, null, [
  3311. 'path' => $path,
  3312. 'cursorName' => $cursorName,
  3313. 'parameters' => ['test'],
  3314. ]), $result);
  3315. }
  3316. public function testCursorPaginateWithSpecificColumns()
  3317. {
  3318. $perPage = 16;
  3319. $columns = ['id', 'name'];
  3320. $cursorName = 'cursor-name';
  3321. $cursor = new Cursor(['id' => 2]);
  3322. $builder = $this->getMockQueryBuilder();
  3323. $builder->from('foobar')->orderBy('id');
  3324. $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {
  3325. return new Builder($builder->connection, $builder->grammar, $builder->processor);
  3326. });
  3327. $path = 'http://foo.bar?cursor=3';
  3328. $results = collect([['id' => 3, 'name' => 'Taylor'], ['id' => 5, 'name' => 'Mohamed']]);
  3329. $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {
  3330. $this->assertEquals(
  3331. 'select * from "foobar" where ("id" > ?) order by "id" asc limit 17',
  3332. $builder->toSql());
  3333. $this->assertEquals([2], $builder->bindings['where']);
  3334. return $results;
  3335. });
  3336. Paginator::currentPathResolver(function () use ($path) {
  3337. return $path;
  3338. });
  3339. $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);
  3340. $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [
  3341. 'path' => $path,
  3342. 'cursorName' => $cursorName,
  3343. 'parameters' => ['id'],
  3344. ]), $result);
  3345. }
  3346. public function testCursorPaginateWithMixedOrders()
  3347. {
  3348. $perPage = 16;
  3349. $columns = ['foo', 'bar', 'baz'];
  3350. $cursorName = 'cursor-name';
  3351. $cursor = new Cursor(['foo' => 1, 'bar' => 2, 'baz' => 3]);
  3352. $builder = $this->getMockQueryBuilder();
  3353. $builder->from('foobar')->orderBy('foo')->orderByDesc('bar')->orderBy('baz');
  3354. $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {
  3355. return new Builder($builder->connection, $builder->grammar, $builder->processor);
  3356. });
  3357. $path = 'http://foo.bar?cursor='.$cursor->encode();
  3358. $results = collect([['foo' => 1, 'bar' => 2, 'baz' => 4], ['foo' => 1, 'bar' => 1, 'baz' => 1]]);
  3359. $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results) {
  3360. $this->assertEquals(
  3361. 'select * from "foobar" where ("foo" > ? or ("foo" = ? and ("bar" < ? or ("bar" = ? and ("baz" > ?))))) order by "foo" asc, "bar" desc, "baz" asc limit 17',
  3362. $builder->toSql()
  3363. );
  3364. $this->assertEquals([1, 1, 2, 2, 3], $builder->bindings['where']);
  3365. return $results;
  3366. });
  3367. Paginator::currentPathResolver(function () use ($path) {
  3368. return $path;
  3369. });
  3370. $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);
  3371. $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [
  3372. 'path' => $path,
  3373. 'cursorName' => $cursorName,
  3374. 'parameters' => ['foo', 'bar', 'baz'],
  3375. ]), $result);
  3376. }
  3377. public function testCursorPaginateWithUnionWheres()
  3378. {
  3379. $ts = now()->toDateTimeString();
  3380. $perPage = 16;
  3381. $columns = ['test'];
  3382. $cursorName = 'cursor-name';
  3383. $cursor = new Cursor(['created_at' => $ts]);
  3384. $builder = $this->getMockQueryBuilder();
  3385. $builder->select('id', 'start_time as created_at')->selectRaw("'video' as type")->from('videos');
  3386. $builder->union($this->getBuilder()->select('id', 'created_at')->selectRaw("'news' as type")->from('news'));
  3387. $builder->orderBy('created_at');
  3388. $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {
  3389. return new Builder($builder->connection, $builder->grammar, $builder->processor);
  3390. });
  3391. $path = 'http://foo.bar?cursor='.$cursor->encode();
  3392. $results = collect([
  3393. ['id' => 1, 'created_at' => now(), 'type' => 'video'],
  3394. ['id' => 2, 'created_at' => now(), 'type' => 'news'],
  3395. ]);
  3396. $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {
  3397. $this->assertEquals(
  3398. '(select "id", "start_time" as "created_at", \'video\' as type from "videos" where ("start_time" > ?)) union (select "id", "created_at", \'news\' as type from "news" where ("start_time" > ?)) order by "created_at" asc limit 17',
  3399. $builder->toSql());
  3400. $this->assertEquals([$ts], $builder->bindings['where']);
  3401. $this->assertEquals([$ts], $builder->bindings['union']);
  3402. return $results;
  3403. });
  3404. Paginator::currentPathResolver(function () use ($path) {
  3405. return $path;
  3406. });
  3407. $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);
  3408. $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [
  3409. 'path' => $path,
  3410. 'cursorName' => $cursorName,
  3411. 'parameters' => ['created_at'],
  3412. ]), $result);
  3413. }
  3414. public function testCursorPaginateWithUnionWheresWithRawOrderExpression()
  3415. {
  3416. $ts = now()->toDateTimeString();
  3417. $perPage = 16;
  3418. $columns = ['test'];
  3419. $cursorName = 'cursor-name';
  3420. $cursor = new Cursor(['created_at' => $ts]);
  3421. $builder = $this->getMockQueryBuilder();
  3422. $builder->select('id', 'is_published', 'start_time as created_at')->selectRaw("'video' as type")->where('is_published', true)->from('videos');
  3423. $builder->union($this->getBuilder()->select('id', 'is_published', 'created_at')->selectRaw("'news' as type")->where('is_published', true)->from('news'));
  3424. $builder->orderByRaw('case when (id = 3 and type="news" then 0 else 1 end)')->orderBy('created_at');
  3425. $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {
  3426. return new Builder($builder->connection, $builder->grammar, $builder->processor);
  3427. });
  3428. $path = 'http://foo.bar?cursor='.$cursor->encode();
  3429. $results = collect([
  3430. ['id' => 1, 'created_at' => now(), 'type' => 'video', 'is_published' => true],
  3431. ['id' => 2, 'created_at' => now(), 'type' => 'news', 'is_published' => true],
  3432. ]);
  3433. $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {
  3434. $this->assertEquals(
  3435. '(select "id", "is_published", "start_time" as "created_at", \'video\' as type from "videos" where "is_published" = ? and ("start_time" > ?)) union (select "id", "is_published", "created_at", \'news\' as type from "news" where "is_published" = ? and ("start_time" > ?)) order by case when (id = 3 and type="news" then 0 else 1 end), "created_at" asc limit 17',
  3436. $builder->toSql());
  3437. $this->assertEquals([true, $ts], $builder->bindings['where']);
  3438. $this->assertEquals([true, $ts], $builder->bindings['union']);
  3439. return $results;
  3440. });
  3441. Paginator::currentPathResolver(function () use ($path) {
  3442. return $path;
  3443. });
  3444. $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);
  3445. $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [
  3446. 'path' => $path,
  3447. 'cursorName' => $cursorName,
  3448. 'parameters' => ['created_at'],
  3449. ]), $result);
  3450. }
  3451. public function testCursorPaginateWithUnionWheresReverseOrder()
  3452. {
  3453. $ts = now()->toDateTimeString();
  3454. $perPage = 16;
  3455. $columns = ['test'];
  3456. $cursorName = 'cursor-name';
  3457. $cursor = new Cursor(['created_at' => $ts], false);
  3458. $builder = $this->getMockQueryBuilder();
  3459. $builder->select('id', 'start_time as created_at')->selectRaw("'video' as type")->from('videos');
  3460. $builder->union($this->getBuilder()->select('id', 'created_at')->selectRaw("'news' as type")->from('news'));
  3461. $builder->orderBy('created_at');
  3462. $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {
  3463. return new Builder($builder->connection, $builder->grammar, $builder->processor);
  3464. });
  3465. $path = 'http://foo.bar?cursor='.$cursor->encode();
  3466. $results = collect([
  3467. ['id' => 1, 'created_at' => now(), 'type' => 'video'],
  3468. ['id' => 2, 'created_at' => now(), 'type' => 'news'],
  3469. ]);
  3470. $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {
  3471. $this->assertEquals(
  3472. '(select "id", "start_time" as "created_at", \'video\' as type from "videos" where ("start_time" < ?)) union (select "id", "created_at", \'news\' as type from "news" where ("start_time" < ?)) order by "created_at" asc limit 17',
  3473. $builder->toSql());
  3474. $this->assertEquals([$ts], $builder->bindings['where']);
  3475. $this->assertEquals([$ts], $builder->bindings['union']);
  3476. return $results;
  3477. });
  3478. Paginator::currentPathResolver(function () use ($path) {
  3479. return $path;
  3480. });
  3481. $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);
  3482. $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [
  3483. 'path' => $path,
  3484. 'cursorName' => $cursorName,
  3485. 'parameters' => ['created_at'],
  3486. ]), $result);
  3487. }
  3488. public function testCursorPaginateWithUnionWheresMultipleOrders()
  3489. {
  3490. $ts = now()->toDateTimeString();
  3491. $perPage = 16;
  3492. $columns = ['test'];
  3493. $cursorName = 'cursor-name';
  3494. $cursor = new Cursor(['created_at' => $ts, 'id' => 1]);
  3495. $builder = $this->getMockQueryBuilder();
  3496. $builder->select('id', 'start_time as created_at')->selectRaw("'video' as type")->from('videos');
  3497. $builder->union($this->getBuilder()->select('id', 'created_at')->selectRaw("'news' as type")->from('news'));
  3498. $builder->orderByDesc('created_at')->orderBy('id');
  3499. $builder->shouldReceive('newQuery')->andReturnUsing(function () use ($builder) {
  3500. return new Builder($builder->connection, $builder->grammar, $builder->processor);
  3501. });
  3502. $path = 'http://foo.bar?cursor='.$cursor->encode();
  3503. $results = collect([
  3504. ['id' => 1, 'created_at' => now(), 'type' => 'video'],
  3505. ['id' => 2, 'created_at' => now(), 'type' => 'news'],
  3506. ]);
  3507. $builder->shouldReceive('get')->once()->andReturnUsing(function () use ($builder, $results, $ts) {
  3508. $this->assertEquals(
  3509. '(select "id", "start_time" as "created_at", \'video\' as type from "videos" where ("start_time" < ? or ("start_time" = ? and ("id" > ?)))) union (select "id", "created_at", \'news\' as type from "news" where ("start_time" < ? or ("start_time" = ? and ("id" > ?)))) order by "created_at" desc, "id" asc limit 17',
  3510. $builder->toSql());
  3511. $this->assertEquals([$ts, $ts, 1], $builder->bindings['where']);
  3512. $this->assertEquals([$ts, $ts, 1], $builder->bindings['union']);
  3513. return $results;
  3514. });
  3515. Paginator::currentPathResolver(function () use ($path) {
  3516. return $path;
  3517. });
  3518. $result = $builder->cursorPaginate($perPage, $columns, $cursorName, $cursor);
  3519. $this->assertEquals(new CursorPaginator($results, $perPage, $cursor, [
  3520. 'path' => $path,
  3521. 'cursorName' => $cursorName,
  3522. 'parameters' => ['created_at', 'id'],
  3523. ]), $result);
  3524. }
  3525. public function testWhereRowValues()
  3526. {
  3527. $builder = $this->getBuilder();
  3528. $builder->select('*')->from('orders')->whereRowValues(['last_update', 'order_number'], '<', [1, 2]);
  3529. $this->assertSame('select * from "orders" where ("last_update", "order_number") < (?, ?)', $builder->toSql());
  3530. $builder = $this->getBuilder();
  3531. $builder->select('*')->from('orders')->where('company_id', 1)->orWhereRowValues(['last_update', 'order_number'], '<', [1, 2]);
  3532. $this->assertSame('select * from "orders" where "company_id" = ? or ("last_update", "order_number") < (?, ?)', $builder->toSql());
  3533. $builder = $this->getBuilder();
  3534. $builder->select('*')->from('orders')->whereRowValues(['last_update', 'order_number'], '<', [1, new Raw('2')]);
  3535. $this->assertSame('select * from "orders" where ("last_update", "order_number") < (?, 2)', $builder->toSql());
  3536. $this->assertEquals([1], $builder->getBindings());
  3537. }
  3538. public function testWhereRowValuesArityMismatch()
  3539. {
  3540. $this->expectException(InvalidArgumentException::class);
  3541. $this->expectExceptionMessage('The number of columns must match the number of values');
  3542. $builder = $this->getBuilder();
  3543. $builder->select('*')->from('orders')->whereRowValues(['last_update'], '<', [1, 2]);
  3544. }
  3545. public function testWhereJsonContainsMySql()
  3546. {
  3547. $builder = $this->getMySqlBuilder();
  3548. $builder->select('*')->from('users')->whereJsonContains('options', ['en']);
  3549. $this->assertSame('select * from `users` where json_contains(`options`, ?)', $builder->toSql());
  3550. $this->assertEquals(['["en"]'], $builder->getBindings());
  3551. $builder = $this->getMySqlBuilder();
  3552. $builder->select('*')->from('users')->whereJsonContains('users.options->languages', ['en']);
  3553. $this->assertSame('select * from `users` where json_contains(`users`.`options`, ?, \'$."languages"\')', $builder->toSql());
  3554. $this->assertEquals(['["en"]'], $builder->getBindings());
  3555. $builder = $this->getMySqlBuilder();
  3556. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContains('options->languages', new Raw("'[\"en\"]'"));
  3557. $this->assertSame('select * from `users` where `id` = ? or json_contains(`options`, \'["en"]\', \'$."languages"\')', $builder->toSql());
  3558. $this->assertEquals([1], $builder->getBindings());
  3559. }
  3560. public function testWhereJsonContainsPostgres()
  3561. {
  3562. $builder = $this->getPostgresBuilder();
  3563. $builder->select('*')->from('users')->whereJsonContains('options', ['en']);
  3564. $this->assertSame('select * from "users" where ("options")::jsonb @> ?', $builder->toSql());
  3565. $this->assertEquals(['["en"]'], $builder->getBindings());
  3566. $builder = $this->getPostgresBuilder();
  3567. $builder->select('*')->from('users')->whereJsonContains('users.options->languages', ['en']);
  3568. $this->assertSame('select * from "users" where ("users"."options"->\'languages\')::jsonb @> ?', $builder->toSql());
  3569. $this->assertEquals(['["en"]'], $builder->getBindings());
  3570. $builder = $this->getPostgresBuilder();
  3571. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContains('options->languages', new Raw("'[\"en\"]'"));
  3572. $this->assertSame('select * from "users" where "id" = ? or ("options"->\'languages\')::jsonb @> \'["en"]\'', $builder->toSql());
  3573. $this->assertEquals([1], $builder->getBindings());
  3574. }
  3575. public function testWhereJsonContainsSqlite()
  3576. {
  3577. $this->expectException(RuntimeException::class);
  3578. $builder = $this->getSQLiteBuilder();
  3579. $builder->select('*')->from('users')->whereJsonContains('options->languages', ['en'])->toSql();
  3580. }
  3581. public function testWhereJsonContainsSqlServer()
  3582. {
  3583. $builder = $this->getSqlServerBuilder();
  3584. $builder->select('*')->from('users')->whereJsonContains('options', true);
  3585. $this->assertSame('select * from [users] where ? in (select [value] from openjson([options]))', $builder->toSql());
  3586. $this->assertEquals(['true'], $builder->getBindings());
  3587. $builder = $this->getSqlServerBuilder();
  3588. $builder->select('*')->from('users')->whereJsonContains('users.options->languages', 'en');
  3589. $this->assertSame('select * from [users] where ? in (select [value] from openjson([users].[options], \'$."languages"\'))', $builder->toSql());
  3590. $this->assertEquals(['en'], $builder->getBindings());
  3591. $builder = $this->getSqlServerBuilder();
  3592. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonContains('options->languages', new Raw("'en'"));
  3593. $this->assertSame('select * from [users] where [id] = ? or \'en\' in (select [value] from openjson([options], \'$."languages"\'))', $builder->toSql());
  3594. $this->assertEquals([1], $builder->getBindings());
  3595. }
  3596. public function testWhereJsonDoesntContainMySql()
  3597. {
  3598. $builder = $this->getMySqlBuilder();
  3599. $builder->select('*')->from('users')->whereJsonDoesntContain('options->languages', ['en']);
  3600. $this->assertSame('select * from `users` where not json_contains(`options`, ?, \'$."languages"\')', $builder->toSql());
  3601. $this->assertEquals(['["en"]'], $builder->getBindings());
  3602. $builder = $this->getMySqlBuilder();
  3603. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContain('options->languages', new Raw("'[\"en\"]'"));
  3604. $this->assertSame('select * from `users` where `id` = ? or not json_contains(`options`, \'["en"]\', \'$."languages"\')', $builder->toSql());
  3605. $this->assertEquals([1], $builder->getBindings());
  3606. }
  3607. public function testWhereJsonDoesntContainPostgres()
  3608. {
  3609. $builder = $this->getPostgresBuilder();
  3610. $builder->select('*')->from('users')->whereJsonDoesntContain('options->languages', ['en']);
  3611. $this->assertSame('select * from "users" where not ("options"->\'languages\')::jsonb @> ?', $builder->toSql());
  3612. $this->assertEquals(['["en"]'], $builder->getBindings());
  3613. $builder = $this->getPostgresBuilder();
  3614. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContain('options->languages', new Raw("'[\"en\"]'"));
  3615. $this->assertSame('select * from "users" where "id" = ? or not ("options"->\'languages\')::jsonb @> \'["en"]\'', $builder->toSql());
  3616. $this->assertEquals([1], $builder->getBindings());
  3617. }
  3618. public function testWhereJsonDoesntContainSqlite()
  3619. {
  3620. $this->expectException(RuntimeException::class);
  3621. $builder = $this->getSQLiteBuilder();
  3622. $builder->select('*')->from('users')->whereJsonDoesntContain('options->languages', ['en'])->toSql();
  3623. }
  3624. public function testWhereJsonDoesntContainSqlServer()
  3625. {
  3626. $builder = $this->getSqlServerBuilder();
  3627. $builder->select('*')->from('users')->whereJsonDoesntContain('options->languages', 'en');
  3628. $this->assertSame('select * from [users] where not ? in (select [value] from openjson([options], \'$."languages"\'))', $builder->toSql());
  3629. $this->assertEquals(['en'], $builder->getBindings());
  3630. $builder = $this->getSqlServerBuilder();
  3631. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonDoesntContain('options->languages', new Raw("'en'"));
  3632. $this->assertSame('select * from [users] where [id] = ? or not \'en\' in (select [value] from openjson([options], \'$."languages"\'))', $builder->toSql());
  3633. $this->assertEquals([1], $builder->getBindings());
  3634. }
  3635. public function testWhereJsonLengthMySql()
  3636. {
  3637. $builder = $this->getMySqlBuilder();
  3638. $builder->select('*')->from('users')->whereJsonLength('options', 0);
  3639. $this->assertSame('select * from `users` where json_length(`options`) = ?', $builder->toSql());
  3640. $this->assertEquals([0], $builder->getBindings());
  3641. $builder = $this->getMySqlBuilder();
  3642. $builder->select('*')->from('users')->whereJsonLength('users.options->languages', '>', 0);
  3643. $this->assertSame('select * from `users` where json_length(`users`.`options`, \'$."languages"\') > ?', $builder->toSql());
  3644. $this->assertEquals([0], $builder->getBindings());
  3645. $builder = $this->getMySqlBuilder();
  3646. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', new Raw('0'));
  3647. $this->assertSame('select * from `users` where `id` = ? or json_length(`options`, \'$."languages"\') = 0', $builder->toSql());
  3648. $this->assertEquals([1], $builder->getBindings());
  3649. $builder = $this->getMySqlBuilder();
  3650. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', '>', new Raw('0'));
  3651. $this->assertSame('select * from `users` where `id` = ? or json_length(`options`, \'$."languages"\') > 0', $builder->toSql());
  3652. $this->assertEquals([1], $builder->getBindings());
  3653. }
  3654. public function testWhereJsonLengthPostgres()
  3655. {
  3656. $builder = $this->getPostgresBuilder();
  3657. $builder->select('*')->from('users')->whereJsonLength('options', 0);
  3658. $this->assertSame('select * from "users" where json_array_length(("options")::json) = ?', $builder->toSql());
  3659. $this->assertEquals([0], $builder->getBindings());
  3660. $builder = $this->getPostgresBuilder();
  3661. $builder->select('*')->from('users')->whereJsonLength('users.options->languages', '>', 0);
  3662. $this->assertSame('select * from "users" where json_array_length(("users"."options"->\'languages\')::json) > ?', $builder->toSql());
  3663. $this->assertEquals([0], $builder->getBindings());
  3664. $builder = $this->getPostgresBuilder();
  3665. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', new Raw('0'));
  3666. $this->assertSame('select * from "users" where "id" = ? or json_array_length(("options"->\'languages\')::json) = 0', $builder->toSql());
  3667. $this->assertEquals([1], $builder->getBindings());
  3668. $builder = $this->getPostgresBuilder();
  3669. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', '>', new Raw('0'));
  3670. $this->assertSame('select * from "users" where "id" = ? or json_array_length(("options"->\'languages\')::json) > 0', $builder->toSql());
  3671. $this->assertEquals([1], $builder->getBindings());
  3672. }
  3673. public function testWhereJsonLengthSqlite()
  3674. {
  3675. $builder = $this->getSQLiteBuilder();
  3676. $builder->select('*')->from('users')->whereJsonLength('options', 0);
  3677. $this->assertSame('select * from "users" where json_array_length("options") = ?', $builder->toSql());
  3678. $this->assertEquals([0], $builder->getBindings());
  3679. $builder = $this->getSQLiteBuilder();
  3680. $builder->select('*')->from('users')->whereJsonLength('users.options->languages', '>', 0);
  3681. $this->assertSame('select * from "users" where json_array_length("users"."options", \'$."languages"\') > ?', $builder->toSql());
  3682. $this->assertEquals([0], $builder->getBindings());
  3683. $builder = $this->getSQLiteBuilder();
  3684. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', new Raw('0'));
  3685. $this->assertSame('select * from "users" where "id" = ? or json_array_length("options", \'$."languages"\') = 0', $builder->toSql());
  3686. $this->assertEquals([1], $builder->getBindings());
  3687. $builder = $this->getSQLiteBuilder();
  3688. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', '>', new Raw('0'));
  3689. $this->assertSame('select * from "users" where "id" = ? or json_array_length("options", \'$."languages"\') > 0', $builder->toSql());
  3690. $this->assertEquals([1], $builder->getBindings());
  3691. }
  3692. public function testWhereJsonLengthSqlServer()
  3693. {
  3694. $builder = $this->getSqlServerBuilder();
  3695. $builder->select('*')->from('users')->whereJsonLength('options', 0);
  3696. $this->assertSame('select * from [users] where (select count(*) from openjson([options])) = ?', $builder->toSql());
  3697. $this->assertEquals([0], $builder->getBindings());
  3698. $builder = $this->getSqlServerBuilder();
  3699. $builder->select('*')->from('users')->whereJsonLength('users.options->languages', '>', 0);
  3700. $this->assertSame('select * from [users] where (select count(*) from openjson([users].[options], \'$."languages"\')) > ?', $builder->toSql());
  3701. $this->assertEquals([0], $builder->getBindings());
  3702. $builder = $this->getSqlServerBuilder();
  3703. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', new Raw('0'));
  3704. $this->assertSame('select * from [users] where [id] = ? or (select count(*) from openjson([options], \'$."languages"\')) = 0', $builder->toSql());
  3705. $this->assertEquals([1], $builder->getBindings());
  3706. $builder = $this->getSqlServerBuilder();
  3707. $builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonLength('options->languages', '>', new Raw('0'));
  3708. $this->assertSame('select * from [users] where [id] = ? or (select count(*) from openjson([options], \'$."languages"\')) > 0', $builder->toSql());
  3709. $this->assertEquals([1], $builder->getBindings());
  3710. }
  3711. public function testFromSub()
  3712. {
  3713. $builder = $this->getBuilder();
  3714. $builder->fromSub(function ($query) {
  3715. $query->select(new Raw('max(last_seen_at) as last_seen_at'))->from('user_sessions')->where('foo', '=', '1');
  3716. }, 'sessions')->where('bar', '<', '10');
  3717. $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from "user_sessions" where "foo" = ?) as "sessions" where "bar" < ?', $builder->toSql());
  3718. $this->assertEquals(['1', '10'], $builder->getBindings());
  3719. $this->expectException(InvalidArgumentException::class);
  3720. $builder = $this->getBuilder();
  3721. $builder->fromSub(['invalid'], 'sessions')->where('bar', '<', '10');
  3722. }
  3723. public function testFromSubWithPrefix()
  3724. {
  3725. $builder = $this->getBuilder();
  3726. $builder->getGrammar()->setTablePrefix('prefix_');
  3727. $builder->fromSub(function ($query) {
  3728. $query->select(new Raw('max(last_seen_at) as last_seen_at'))->from('user_sessions')->where('foo', '=', '1');
  3729. }, 'sessions')->where('bar', '<', '10');
  3730. $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from "prefix_user_sessions" where "foo" = ?) as "prefix_sessions" where "bar" < ?', $builder->toSql());
  3731. $this->assertEquals(['1', '10'], $builder->getBindings());
  3732. }
  3733. public function testFromSubWithoutBindings()
  3734. {
  3735. $builder = $this->getBuilder();
  3736. $builder->fromSub(function ($query) {
  3737. $query->select(new Raw('max(last_seen_at) as last_seen_at'))->from('user_sessions');
  3738. }, 'sessions');
  3739. $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from "user_sessions") as "sessions"', $builder->toSql());
  3740. $this->expectException(InvalidArgumentException::class);
  3741. $builder = $this->getBuilder();
  3742. $builder->fromSub(['invalid'], 'sessions');
  3743. }
  3744. public function testFromRaw()
  3745. {
  3746. $builder = $this->getBuilder();
  3747. $builder->fromRaw(new Raw('(select max(last_seen_at) as last_seen_at from "user_sessions") as "sessions"'));
  3748. $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from "user_sessions") as "sessions"', $builder->toSql());
  3749. }
  3750. public function testFromRawOnSqlServer()
  3751. {
  3752. $builder = $this->getSqlServerBuilder();
  3753. $builder->fromRaw('dbo.[SomeNameWithRoundBrackets (test)]');
  3754. $this->assertSame('select * from dbo.[SomeNameWithRoundBrackets (test)]', $builder->toSql());
  3755. }
  3756. public function testFromRawWithWhereOnTheMainQuery()
  3757. {
  3758. $builder = $this->getBuilder();
  3759. $builder->fromRaw(new Raw('(select max(last_seen_at) as last_seen_at from "sessions") as "last_seen_at"'))->where('last_seen_at', '>', '1520652582');
  3760. $this->assertSame('select * from (select max(last_seen_at) as last_seen_at from "sessions") as "last_seen_at" where "last_seen_at" > ?', $builder->toSql());
  3761. $this->assertEquals(['1520652582'], $builder->getBindings());
  3762. }
  3763. public function testFromQuestionMarkOperatorOnPostgres()
  3764. {
  3765. $builder = $this->getPostgresBuilder();
  3766. $builder->select('*')->from('users')->where('roles', '?', 'superuser');
  3767. $this->assertSame('select * from "users" where "roles" ?? ?', $builder->toSql());
  3768. $builder = $this->getPostgresBuilder();
  3769. $builder->select('*')->from('users')->where('roles', '?|', 'superuser');
  3770. $this->assertSame('select * from "users" where "roles" ??| ?', $builder->toSql());
  3771. $builder = $this->getPostgresBuilder();
  3772. $builder->select('*')->from('users')->where('roles', '?&', 'superuser');
  3773. $this->assertSame('select * from "users" where "roles" ??& ?', $builder->toSql());
  3774. }
  3775. public function testClone()
  3776. {
  3777. $builder = $this->getBuilder();
  3778. $builder->select('*')->from('users');
  3779. $clone = $builder->clone()->where('email', 'foo');
  3780. $this->assertNotSame($builder, $clone);
  3781. $this->assertSame('select * from "users"', $builder->toSql());
  3782. $this->assertSame('select * from "users" where "email" = ?', $clone->toSql());
  3783. }
  3784. public function testCloneWithout()
  3785. {
  3786. $builder = $this->getBuilder();
  3787. $builder->select('*')->from('users')->where('email', 'foo')->orderBy('email');
  3788. $clone = $builder->cloneWithout(['orders']);
  3789. $this->assertSame('select * from "users" where "email" = ? order by "email" asc', $builder->toSql());
  3790. $this->assertSame('select * from "users" where "email" = ?', $clone->toSql());
  3791. }
  3792. public function testCloneWithoutBindings()
  3793. {
  3794. $builder = $this->getBuilder();
  3795. $builder->select('*')->from('users')->where('email', 'foo')->orderBy('email');
  3796. $clone = $builder->cloneWithout(['wheres'])->cloneWithoutBindings(['where']);
  3797. $this->assertSame('select * from "users" where "email" = ? order by "email" asc', $builder->toSql());
  3798. $this->assertEquals([0 => 'foo'], $builder->getBindings());
  3799. $this->assertSame('select * from "users" order by "email" asc', $clone->toSql());
  3800. $this->assertEquals([], $clone->getBindings());
  3801. }
  3802. protected function getConnection()
  3803. {
  3804. $connection = m::mock(ConnectionInterface::class);
  3805. $connection->shouldReceive('getDatabaseName')->andReturn('database');
  3806. return $connection;
  3807. }
  3808. protected function getBuilder()
  3809. {
  3810. $grammar = new Grammar;
  3811. $processor = m::mock(Processor::class);
  3812. return new Builder($this->getConnection(), $grammar, $processor);
  3813. }
  3814. protected function getPostgresBuilder()
  3815. {
  3816. $grammar = new PostgresGrammar;
  3817. $processor = m::mock(Processor::class);
  3818. return new Builder($this->getConnection(), $grammar, $processor);
  3819. }
  3820. protected function getMySqlBuilder()
  3821. {
  3822. $grammar = new MySqlGrammar;
  3823. $processor = m::mock(Processor::class);
  3824. return new Builder(m::mock(ConnectionInterface::class), $grammar, $processor);
  3825. }
  3826. protected function getSQLiteBuilder()
  3827. {
  3828. $grammar = new SQLiteGrammar;
  3829. $processor = m::mock(Processor::class);
  3830. return new Builder(m::mock(ConnectionInterface::class), $grammar, $processor);
  3831. }
  3832. protected function getSqlServerBuilder()
  3833. {
  3834. $grammar = new SqlServerGrammar;
  3835. $processor = m::mock(Processor::class);
  3836. return new Builder($this->getConnection(), $grammar, $processor);
  3837. }
  3838. protected function getMySqlBuilderWithProcessor()
  3839. {
  3840. $grammar = new MySqlGrammar;
  3841. $processor = new MySqlProcessor;
  3842. return new Builder(m::mock(ConnectionInterface::class), $grammar, $processor);
  3843. }
  3844. protected function getPostgresBuilderWithProcessor()
  3845. {
  3846. $grammar = new PostgresGrammar;
  3847. $processor = new PostgresProcessor;
  3848. return new Builder(m::mock(ConnectionInterface::class), $grammar, $processor);
  3849. }
  3850. /**
  3851. * @return \Mockery\MockInterface|\Illuminate\Database\Query\Builder
  3852. */
  3853. protected function getMockQueryBuilder()
  3854. {
  3855. return m::mock(Builder::class, [
  3856. m::mock(ConnectionInterface::class),
  3857. new Grammar,
  3858. m::mock(Processor::class),
  3859. ])->makePartial();
  3860. }
  3861. }