Bug 1352502 - Part 1. Add `description` and `preview_image_url` to Places. r?mak draft
authorNan Jiang <najiang@mozilla.com>
Tue, 23 May 2017 14:54:13 -0400
changeset 584479 45467fe4017403ffb6ac5927fdb102453e236ba7
parent 583025 6dfa56094f0cc291945dd3c24d0a4c2682d80ec7
child 584480 7c7a1fbb3391d730603bddec4dc3be70a86f6dfd
child 586564 631f63699fad27520ad3c2f4d857e765e96942db
child 599198 7e78f5655aeae97d189ab9fc1af98ec2fa5a6413
child 599756 a28e467241e2095f21a7438cf577ea202f4b18cc
child 599911 e9004db90f47d9a5951dd4f6c90cd5e241f8e180
push id60749
push usernajiang@mozilla.com
push dateThu, 25 May 2017 14:27:09 +0000
reviewersmak
bugs1352502
milestone55.0a1
Bug 1352502 - Part 1. Add `description` and `preview_image_url` to Places. r?mak MozReview-Commit-ID: 4dvVboTm4kf
toolkit/components/places/Database.cpp
toolkit/components/places/Database.h
toolkit/components/places/nsPlacesTables.h
toolkit/components/places/tests/head_common.js
toolkit/components/places/tests/migration/places_v38.sqlite
toolkit/components/places/tests/migration/test_current_from_v38.js
toolkit/components/places/tests/migration/xpcshell.ini
--- a/toolkit/components/places/Database.cpp
+++ b/toolkit/components/places/Database.cpp
@@ -1076,16 +1076,22 @@ Database::InitSchema(bool* aDatabaseMigr
 
       if (currentSchemaVersion < 37) {
         rv = MigrateV37Up();
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
       // Firefox 55 uses schema version 37.
 
+      if (currentSchemaVersion < 38) {
+        rv = MigrateV38Up();
+        NS_ENSURE_SUCCESS(rv, rv);
+      }
+      // Firefox 56 uses schema version 38.
+
       // Schema Upgrades must add migration code here.
 
       rv = UpdateBookmarkRootTitles();
       // We don't want a broken localization to cause us to think
       // the database is corrupt and needs to be replaced.
       MOZ_ASSERT(NS_SUCCEEDED(rv));
     }
   }
@@ -2269,16 +2275,40 @@ Database::MigrateV37Up() {
 
   // Start the async conversion
   nsFaviconService::ConvertUnsupportedPayloads(mMainConn);
 
   return NS_OK;
 }
 
 nsresult
+Database::MigrateV38Up()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsCOMPtr<mozIStorageStatement> stmt;
+  nsresult rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
+    "SELECT description, preview_image_url FROM moz_places"
+  ), getter_AddRefs(stmt));
+  if (NS_FAILED(rv)) {
+    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
+      "ALTER TABLE moz_places ADD COLUMN description TEXT"
+    ));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
+      "ALTER TABLE moz_places ADD COLUMN preview_image_url TEXT"
+    ));
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  return NS_OK;
+}
+
+nsresult
 Database::GetItemsWithAnno(const nsACString& aAnnoName, int32_t aItemType,
                            nsTArray<int64_t>& aItemIds)
 {
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
     "SELECT b.id FROM moz_items_annos a "
     "JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id "
     "JOIN moz_bookmarks b ON b.id = a.item_id "
--- a/toolkit/components/places/Database.h
+++ b/toolkit/components/places/Database.h
@@ -13,17 +13,17 @@
 #include "mozilla/storage.h"
 #include "mozilla/storage/StatementCache.h"
 #include "mozilla/Attributes.h"
 #include "nsIEventTarget.h"
 #include "Shutdown.h"
 
 // This is the schema version. Update it at any schema change and add a
 // corresponding migrateVxx method below.
-#define DATABASE_SCHEMA_VERSION 37
+#define DATABASE_SCHEMA_VERSION 38
 
 // Fired after Places inited.
 #define TOPIC_PLACES_INIT_COMPLETE "places-init-complete"
 // Fired when initialization fails due to a locked database.
 #define TOPIC_DATABASE_LOCKED "places-database-locked"
 // This topic is received when the profile is about to be lost.  Places does
 // initial shutdown work and notifies TOPIC_PLACES_SHUTDOWN to all listeners.
 // Any shutdown work that requires the Places APIs should happen here.
@@ -283,16 +283,17 @@ protected:
   nsresult MigrateV30Up();
   nsresult MigrateV31Up();
   nsresult MigrateV32Up();
   nsresult MigrateV33Up();
   nsresult MigrateV34Up();
   nsresult MigrateV35Up();
   nsresult MigrateV36Up();
   nsresult MigrateV37Up();
+  nsresult MigrateV38Up();
 
   nsresult UpdateBookmarkRootTitles();
 
   friend class ConnectionShutdownBlocker;
 
   int64_t CreateMobileRoot();
   nsresult GetItemsWithAnno(const nsACString& aAnnoName, int32_t aItemType,
                             nsTArray<int64_t>& aItemIds);
--- a/toolkit/components/places/nsPlacesTables.h
+++ b/toolkit/components/places/nsPlacesTables.h
@@ -17,16 +17,18 @@
     ", visit_count INTEGER DEFAULT 0" \
     ", hidden INTEGER DEFAULT 0 NOT NULL" \
     ", typed INTEGER DEFAULT 0 NOT NULL" \
     ", frecency INTEGER DEFAULT -1 NOT NULL" \
     ", last_visit_date INTEGER " \
     ", guid TEXT" \
     ", foreign_count INTEGER DEFAULT 0 NOT NULL" \
     ", url_hash INTEGER DEFAULT 0 NOT NULL " \
+    ", description TEXT" \
+    ", preview_image_url TEXT" \
   ")" \
 )
 
 #define CREATE_MOZ_HISTORYVISITS NS_LITERAL_CSTRING( \
   "CREATE TABLE moz_historyvisits (" \
     "  id INTEGER PRIMARY KEY" \
     ", from_visit INTEGER" \
     ", place_id INTEGER" \
--- a/toolkit/components/places/tests/head_common.js
+++ b/toolkit/components/places/tests/head_common.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // It is expected that the test files importing this file define Cu etc.
 /* global Cu, Ci, Cc, Cr */
 
-const CURRENT_SCHEMA_VERSION = 37;
+const CURRENT_SCHEMA_VERSION = 38;
 const FIRST_UPGRADABLE_SCHEMA_VERSION = 11;
 
 const NS_APP_USER_PROFILE_50_DIR = "ProfD";
 const NS_APP_PROFILE_DIR_STARTUP = "ProfDS";
 
 // Shortcuts to transitions type.
 const TRANSITION_LINK = Ci.nsINavHistoryService.TRANSITION_LINK;
 const TRANSITION_TYPED = Ci.nsINavHistoryService.TRANSITION_TYPED;
new file mode 100644
index 0000000000000000000000000000000000000000..5df92ec55c47a6c872d3899641d535bea7484c91
GIT binary patch
literal 1114112
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
z00000;M>*yzW(5Nus)v%HWhN6KMMbr_TOHA{E;^`qekoT;fLQ;D_uSjHfO4>=HtWL
zheqnp?AbpOK6hsO*y$kn+QX-x{^XV)F7yX`miN+W{^+vShxT6>JM+wuD-Rzyc&^?0
zkx&21&mYbA2m6AZN#k_Vx@W4@nr^;j+qR^ade|DOMYEM^wKNnpCbvyCqM=f?TA7V%
zL#?o0s!k6DFHK(DabVw>*65D2vu8JNJaYA(H=gTV7u@I#9$4OEtui)NX$_4>wQWx{
z!^Xw1@pz>%zIcQ;jZc;8^|1Q*rX4%$mC31A^-3)oA8NH5){?QpLkCaRn&q*PeOsU2
zyzz-M_r7_1u0MD%2<C>$mByl()?3CKrRG%F3|=~R@%Zqb;X~y^v&|Dh@V;OEwc<yA
z{Yp<VyL(oyw^S}i_2!cGhV`wdPi~v2G{TAKa<{^^xoK@}h0Rvj*xHJsYIDiPH0x2h
zTuLT;a(v{-_C3?5wmv<vck{-Vwm)^?*=&C>5<J!&IkhlyIlLHFqv^1*=4Lm->8P62
zDkt4;zqtR&{nHo1^T%6Jdh^C#{JE(QoyznF2ZP<q`yHE^>~^<Sx1DryW-RIT$n3$r
z)3X<L@0l8TB<b}Nubg|^Thsl)(cp>Y`!rUKCWq#BVa=YeR9jP%mHN<RRBiVj&YT&2
z@|jD~Gmkv~<mQbZ`qqt4olW%zqrukYonN|iX_aqaJgT=Em9d#txMYxa<=~|&=MEn~
z)7p3T;oAP;%^N5F@cnP^Z{JzhZ}XiE00000000000000000000000000000000000
z0002DS%3R*{Webm000000000000000000000000000000000000001Pv%dD>`fZ*B
z000000000000000000000000000000000000002oX8p;hH~!He{)_l`;t$3z#nbUW
zNwNR{000000000000000000000000000000000000Pqj;y53wcoX!W+)lxld4b`IA
zO0`-ViW-x_OB-{!;QpknRv8<sw1&o`TJX~Adb;&X<#JSSF0KFiY%bWHl$FDaVKtf#
z8%vAt&E$ezN%7dsWH-8`w3yBXkGD&!(d1CQGC9?%URhe>?o=*#pgo<%!M<b-y>U5+
zKOg^Y{O{uT#6KCoJ;?$9000000000000000000000000000000000000Koru-=7&y
zO;=0xur*YRW-HZdX((z;_O8o3P*{{-m$^SxtBj3RT0`SeE%(~Y?o>Iv7*?a{u(7yZ
z_BEMZsj->KZeUSC=HATXsj+G_IaIGqPPM9678j=5lPHzTQN6i1+|!@TZ{yp4D~SIn
z{`vU%_)XV7ckMT>&0ZV6`pVT`y*hsNz8C(-3-5X1tuGYc{=bt-000000000000000
z00000000000000000000008i9YRkrTK`KZUlG9vnQ=yPa2R$S2eCxYDFg2e}9v#2%
z?5^hST{{ksKYG`?ppZ)CAL!Oj^`%dQ<6*s3JXM-(b{b6G{WG2P9iMu+R66(ck<*8c
z&eop2lzwbOx8<g}mW9mWsM#t$TWMBWVY$=f@gMoEZWlp*^z@mh4pxqrAANTCX!?iO
zcbcXKJ5BScd_H%q^H<P|hr54(ywfW4%FCTJyXjq}=Z2qa9y>ByJJ33v-oLKf`mwpz
zz4@N~mFD<NvspaS{qyF<s9qd7v9H_9PdwF4Kl07`mC1|EeTPS<ckFAWf26<L%htJG
za{26@YPEPJnrRfr8>Qw{*j;|+zCY-uXQy_K?VTArarogYyT>0+@4d6ze%D<4o_uD0
z^iyH86*h{eqNv*KBmE1X>!x3OxwU(AV&c)6$DW%Rem;Hhj&2`M%=MAYr{^}HxPSf+
zycdsztxHkke5ZrdH@@8MsC?|nT}Pj8p1g4Ra2TG<{AgdNqr%R)jxzcAe)i5x7Ed)w
z<LARhw}*STchiq=DDN7n?%sax*l26|aAr@T`)$rIC!K$?(g-J_%L{wj{`>KrronH%
zzngyX*i?CB=Tlp2vuBSVt)vg;I~U%<YSQWS@;*+4&18Sa=e9OzJv#qIU%0&ek@51#
z#F2}~C-aZ?CUZ$Hs7>>$Ihb4-BlU|>^<wwJI{WwM-reot&B5W5d&YL0n>hB|!GkmD
z9l7=t3aQu5UHj>5EgGv-!*=B}U-;>F&!^q!XvYutblYs6yN=VDqphiA-}gq*`C6%Q
zzS(W`!iLVsfA{EXX6h43<8r5QdV99p`kwg_)AKjZe3N$CN@AmP9?x`I6t>New=huW
ziWw_47PoHSL#=MO)4Jy^=}z<f;L7HQ!}`pUw#mI-OJegQ_iRqJ+vfBA^OId(yAegL
z`P%*MhspKZ`z!+h000000000000000000000000000000000000D#-AuYI_Fn<oJP
z00000000000000000000000000000000000006gHfAUGke-XsrNDcr10000000000
z00000000000000000000000000Px+fknRcYP6f4cJ)2MU1b3x^vDr*tQjm_n8pMB-
z8~^|S00000000000000000000000000000000000;Cn`I=I&IjTu=98?kbGU_9u~4
z{7R7g3jhEB00000000000000000000000000000000000-y=4pGMiGhXm<2`c;!;m
zC^ysnNi-9GFo^#={#cR#00000000000000000000000000000000000006+ZyMat5
z*mbO08V{S>PS#3|*4`*OpQPvSPiKOWvAN8#Ml>BZT9u?yIc$zMD$}h>R3AtsZEMk3
zr5bLVuh~2iMXkQ1<4pXkLHy_O$C3m900000000000000000000000000000000000
z006%24P<r|YSCDw8g3hlqVu&<<9zc(6t#XZGm@GQ9BV|=VWU+Eo7>7^bG%WRZdIas
z`ZbwdsbkgBcoIIDRBP>>tDfm^cYOUeFAM+x000000000000000000000000000000
z000000B*DX<dcmb3gXYlSK|}O2><{900000000000000000000000000000000000
z+`>cIz95ylKc7nFa(87;gyUhob*ePk%w~d~k$1lJ9iMu6J{`=oYd+Aaxgm2nYPO!O
zG%KyJJXdup$j_(e(sv|PZ*=Qs(tFC~;#d@&uaz3-o5faCY)w^~#fhj|4jb)kGYpeZ
zSSyw*&FO0CN?0yN^>(DVccIm(D5{Q?8r`wZ{(b(-^XWaQWLkyw`BWjB%?)SIeBobQ
zZ-4rewPoYsApYI>XXAgGoB#j-00000000000000000000000000000000000!2gY{
z+3bTqG*F9XN5`V*e67?t-&~Rzt+c{grCts%KT=Ho*_O#Z_{6QMPnQ~Dy*1ZhXL0zk
zboRlMuhxIH)NIwFa%G|tmKVm_xg(W*aOCb=G@YEOlt*Xkl?yZBT&v-}WJ!JTKMUfo
z$6ts)8-FtXuklCX--tgDzc&d200000000000000000000000000000000000006-4
zaAzi$3WBdaeER86Zt0uPJo4#Z`T0UO^S)pHwc<yAJ=d4%Np0TviC50OEz>>y(6?@U
zD&0N(#h;t{P_}#e()Ong^b|5Zh0Pl${_y>8?*@-tz2}Yj?&%X}?tOD_Uovc8{8SMC
zZT$84OYtY;-;V!P{FCv;`1vFV0000000000000000000000000000000000000030
zK<hIPq-xRlP^&UFR;dm3zCQCrYO)axm8#XsY*ZV%Qf*C5R_a5OQFUx6eRpPSVR7lD
zOP7WQGCP;FXodAsb$TejJl?EF<#K7L=XIIKmc$$3bW{y5hUKB`Ycso-6m`<cnX#cv
zPiB2;sIPM@WHUi3*O$z_FaG@?{#N|g@mJ$7#-EG-EdEUV$MGkUAOHXW0000000000
z0000000000000000000000000d}qpL@~OV|q0m0$+lSuvA=f_iv=7<#A=5sjGnss$
zFKN^le<X<iHvUHZ<@odQpT?h#KN0_4{9lqF000000000000000000000000000000
z000000001dXUJvJso<r2H|gyrxo*<aO|so2(@oMnnRFouX7Z`N_My<1bkZ09eh_~v
z{_FUw@fYLI#eWumCjR626G;#N00000000000000000000000000000000000006!-
zWivsluYD-A5Bc_?w|&U94?XQewtdL759v%MDD<^kUBAt<1^@s6000000000000000
z0000000000000000001h+pMpBxPF@_0RR91000000000000000000000000000000
z00000w^?8NaQ!w<0ssI200000000000000000000000000000000000ZnM7RvoU^0
z5dTg5SMguQ|117X{NLg~h<_*k&+&)je;<D+{y_Zx_&xDIkAEtu1ONa40000000000
z0000000000000000000000000|A=zgR3X)OS0^cK=p^~|ouqeNC&~49lAb#|N%oFT
zlIiOt=|WGokkrg&gH$TBv6H0p-6Ypddb&xrn`F94x+h5r>AqzAjq&v${@eKL@t5My
z#eWk2_xO+E-;F;O|EKsj<9{3foA~|lyW^jU-<4DX0000000000000000000000000
z0000000000004l0B)!>GDwWTz@1{NLx@oq*n`Z9prs+F!*;FBw?@N+=Dqra2GQFK#
zW<#e=I-T!C(;GX{^j*1ZA(hJJI!UIdlccjf*+SAVIVLr-*?hjxm&{?~wQmLSSL6Q~
ze=7cX{M+%b#qW!MHvX}=6^HS&@xl1fcrbold`D6V0000000000000000000000000
z0000000000004mRO6#(zT&geV8F}Yh-|?xJ@9Ja=o$OSQ-_XhCJK5}}cdhSadpp_8
zN4~kPlg)LrXQ%o**`7`|{k50x>}0duZ28z7oouF)O?`YrUniUHWP>jrEA(dzxl}jz
z=AgGf8_eb2^?|94OLFNulU!jwceCj6ANj4!&0OY{m-7p`vw!#KYkC%PXTI>$@6IjC
zy|5wMm+V7d{9F)!DgI3Sd+~?k5616}e<HpdPbNVC0000000000000000000000000
z0000000000008)Zvp%z_aOK?L<7Zm?&OTh*KfEEcDK&X<$ANukTBAG8&YsP;1L4e>
z(I=m|6g~6E^G~KbfkOvR)|%z9k$qdA?rjH7j*lGKzGwQ>)~6@-_Ot`XE*>A=GkmCg
zXtsGG*A5(+J-Byz_QLKxQzMUL+JQs+FN~de=E#+Y4;(yKXa`2>&+OSh5<Yik``GEe
zc3}I({ZH<nz7U>2-ioq)$z(TP`~4vPQv8|t_u>!7AB^7{|3rK_o{XQ355y1055#xJ
z>1$uP_SvKo000000000000000000000000000000000000002rDcXPEex^QAsfOjz
zww`vN6-CvtQlk^dbONQx=IESkC$M{TV&c)6$DW%Re*Vt&nN5X86t(7Sv@2Y=y#0~!
z^2o%Ii^nJP?Lhs?<i+N`!=uwX_O;fv1GQ)@8MWIY*9nC6nfWf#?Z8xdWam>`YqMvM
zAFUMHfytxe7oOeK+`VhZ;qi^_KzY|lb@%pj$3|Pzhx^)rQt8~&M@}C)I$L}8(p{av
zbHmRyj~$t<9cZ0i-wuqPKJ(PU%JK4}&ki5m&<-3vxo2$0xrt-X9XvSG+YUUr>*&+X
zlNT-@4#Sgov;#ZG_Rfr*IQ;OH-Qy4U_a&Q_j{ho%|0X#A00000000000000000000
z000000000000000006-Ej$Aesq_XLrBq?P2+L7zGc}4&L00000000000000000000
z0000000000000000C1c2C7*2kr$PM9_^a_3k`n*`0000000000000000000000000
m00000000000Qj!dn@y!scV)7jbVDZ7lT8&0xlS&VPX8Z~1V4fR
new file mode 100644
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v38.js
@@ -0,0 +1,43 @@
+add_task(function* setup() {
+  yield setupPlacesDatabase("places_v38.sqlite");
+});
+
+add_task(function* database_is_valid() {
+  // Accessing the database for the first time triggers migration.
+  Assert.equal(PlacesUtils.history.databaseStatus,
+               PlacesUtils.history.DATABASE_STATUS_UPGRADED);
+
+  let db = yield PlacesUtils.promiseDBConnection();
+  Assert.equal((yield db.getSchemaVersion()), CURRENT_SCHEMA_VERSION);
+});
+
+add_task(function* test_new_fields() {
+  let path = OS.Path.join(OS.Constants.Path.profileDir, DB_FILENAME);
+  let db = yield Sqlite.openConnection({ path });
+
+  // Manually update these two fields for a places record.
+  yield db.execute(`
+    UPDATE moz_places
+    SET description = :description, preview_image_url = :previewImageURL
+    WHERE id = 1`, { description: "Page description",
+                     previewImageURL: "https://example.com/img.png" });
+  let rows = yield db.execute(`SELECT description FROM moz_places
+                               WHERE description IS NOT NULL
+                               AND preview_image_url IS NOT NULL`);
+  Assert.equal(rows.length, 1,
+    "should fetch one record with not null description and preview_image_url");
+
+  // Reset them to the default value
+  yield db.execute(`
+    UPDATE moz_places
+    SET description = NULL,
+        preview_image_url = NULL
+    WHERE id = 1`);
+  rows = yield db.execute(`SELECT description FROM moz_places
+                           WHERE description IS NOT NULL
+                           AND preview_image_url IS NOT NULL`);
+  Assert.equal(rows.length, 0,
+    "should fetch 0 record with not null description and preview_image_url");
+
+  yield db.close();
+});
--- a/toolkit/components/places/tests/migration/xpcshell.ini
+++ b/toolkit/components/places/tests/migration/xpcshell.ini
@@ -18,22 +18,24 @@ support-files =
   places_v30.sqlite
   places_v31.sqlite
   places_v32.sqlite
   places_v33.sqlite
   places_v34.sqlite
   places_v35.sqlite
   places_v36.sqlite
   places_v37.sqlite
+  places_v38.sqlite
 
 [test_current_from_downgraded.js]
 [test_current_from_v6.js]
 [test_current_from_v11.js]
 [test_current_from_v19.js]
 [test_current_from_v24.js]
 [test_current_from_v25.js]
 [test_current_from_v26.js]
 [test_current_from_v27.js]
 [test_current_from_v31.js]
 [test_current_from_v34.js]
 [test_current_from_v34_no_roots.js]
 [test_current_from_v35.js]
 [test_current_from_v36.js]
+[test_current_from_v38.js]