0

How to display bookmarks that have the same tag labeled 'press_germany' from Places.sqlite database. I use the SQLite Manager extension as well as the DB Browser for SQLite software. I do not see any table of tags, and I do not know how firefox creates these tags.

All that I have found approaching my goal is in the following links:

stackoverflow, superuser.com.

I tried this query but it shows 0 results:

SELECT moz_places.url, moz_places.title   
FROM moz_places    
LEFT OUTER JOIN moz_bookmarks    
ON moz_places.id = moz_bookmarks.fk    
WHERE moz_bookmarks.title = 'press_germany'

Thanks.

A places.sqlite schema if helpful: Mozilla Developer The Places database

amdawb
  • 3
  • 4

4 Answers4

1

When you create a tag in Firefox, it creates an entry in moz_bookmarks where the title column will contain the tag, and the fk (foreign key that points to moz_places.id. Any bookmarks under that tag will have moz_bookmarks.parent pointing to the id of the tag. So the first thing you need to do is find the id of the tag.

SELECT moz_bookmarks.id from moz_bookmarks
WHERE moz_bookmarks.title == 'press_germany' AND moz_bookmarks.fk IS NULL

By including the AND statement, you are ensuring you hit on the tag. If it's an actual bookmark, fk will have a value. We don't want that, we want fk to be NULL.

Now that we have that, we need to use that in a query. You can do that as follows:

SELECT moz_bookmarks.title
FROM moz_bookmarks, (SELECT moz_bookmarks.id from moz_bookmarks
WHERE moz_bookmarks.title == 'press_germany' AND moz_bookmarks.fk IS NULL) tag
WHERE moz_bookmarks.parent == tag.id

Note in the above query, we are using the results of the first query in the FROM statement (much like you did - but commenting for those who may not be familiar with this), and assigning it's results to the alias 'tag' (you can pick whatever alias you want as you probably know, just don't use a reserved word or create a collision with a field name).

Your final statement would look something like this I suspect (if not, I'm pretty sure you will be able to tweak it from there):

SELECT moz_places.id, moz_bookmarks.title, moz_places.url
FROM  moz_bookmarks, (SELECT moz_bookmarks.id from moz_bookmarks
WHERE moz_bookmarks.title == 'press_germany' AND moz_bookmarks.fk IS NULL) tag
LEFT OUTER JOIN moz_places
ON moz_places.id == moz_bookmarks.fk
WHERE moz_bookmarks.parent == tag.id

The above will not do a recursive list. In other words, if you have sub-folders within the folder, the sub-folder names will be listed in your query, but not their content, including sub-sub folders.

If you want to pull all bookmarks recursively, here's a query I was able to come up with by taking someone else's query and tweaking it. Beyond that, I am not skilled at recursive queries.

WITH RECURSIVE
under_root(id, level) AS (
VALUES (0,0)
UNION ALL
SELECT moz_bookmarks.id, under_root.level+1
   FROM moz_bookmarks JOIN under_root ON moz_bookmarks.parent=under_root.id
   ORDER BY 2 DESC
)
SELECT substr('.....................................................................................................',1,level*5) ||  moz_bookmarks.title AS "TITLE", CASE WHEN moz_places.url is null THEN "" ELSE moz_places.url END AS "URL", datetime(moz_bookmarks.dateAdded/1000000,"UNIXEPOCH","LOCALTIME") AS "Date Added", datetime(lastModified/1000000,"UNIXEPOCH","LOCALTIME") AS "Last Modified", CASE WHEN datetime(moz_places.last_visit_date/1000000,"UNIXEPOCH","LOCALTIME") IS null THEN "" ELSE datetime(moz_places.last_visit_date/1000000,'UNIXEPOCH','LOCALTIME') END AS "Last Visit Date", CASE WHEN moz_places.visit_count IS null OR moz_places.visit_count=0 THEN "" ELSE moz_places.visit_count END FROM moz_bookmarks JOIN under_root ON moz_bookmarks.id=under_root.id LEFT JOIN moz_places on moz_places.id=moz_bookmarks.fk;
0

NB: based on Firefox dev 63.0b6

Look at the data in moz_bookmarks more carefully. What is the fk in the row that has the tag title?

The real clue is in the doc [emphasis mine]:

moz_bookmarks: This table contains bookmarks, folders, separators and tags, and defines the hierarchy. The hierarchy is defined via the parent column, which points to the moz_bookmarks record which is the parent. The position column numbers each of the peers beneath a given parent starting with 0 and incrementing higher with each addition. The fk column provides the id number of the corresponding record in moz_places.

These tables are tightly referenced, so a join seems unnecessary. You might start with
FROM moz_places,moz_bookmarks tag, moz_bookmarks childs
and see where that takes you.

--ADDENDUM-->
You need two "types" of rows from moz_bookmarks that are mutually exclusive. The "tag" row, which has a title and an id, but fk is NULL. And the "child" rows from moz_bookmarks that have a parent_key which matches the id of the "tag" row and an fk (which is the id of the corresponding row in moz_places).

The key here is using a "self join". I found this tutorial that may help you learn this concept and build a working query. And in your case, the 'FROM' clause will include moz_places.

As regards the query posted in the comments: No rows will match because it explicitly selects rows with fk = NULL and there are NO ROWS in moz_places with id = NULL.

DinoCoderSaurus
  • 4,485
  • 2
  • 7
  • 12
  • In moz_bookmarks table, ALL rows containing titles corresponding to my tags have fk=NULL and parent=4. – amdawb Sep 15 '18 at 13:16
  • Right. That's what I'd expect. So the join returns no rows. You have to write different query. – DinoCoderSaurus Sep 15 '18 at 13:44
  • I've been looking forward to finding the correct query, but I'm really stuck here. SELECT moz_places.url, moz_places.title FROM moz_places JOIN moz_bookmarks ON moz_places.id = moz_bookmarks.fk WHERE moz_bookmarks.fk=NULL AND moz_bookmarks.parent= 4 AND moz_bookmarks.title='press_germany' unsuccessful syntax? – amdawb Sep 15 '18 at 14:03
  • I have added more info to the answer. Let the learning begin! -oo- – DinoCoderSaurus Sep 15 '18 at 14:27
0

I think I managed to list my 'press_germany' tags.

select * from(
SELECT x.id, x.title as Tag,z.url as Location
FROM moz_bookmarks x, moz_bookmarks y,moz_places z
WHERE x.id = y.parent and y.fk = z.id
)where Tag like 'press_germany'

One last thing: I would like to list my results as follows: {id - Name - Location} but I do not know how to get the 'Name' column. MartinStettner's schema response is very explanatory. the values of 'Name' are to be retrieved in the 'title' field of the first line (stackoverflow). Please help again.

amdawb
  • 3
  • 4
  • I approach the goal, but this request oddly multiplies the rows of the same bookmark (bookmark entries), by 2.3 or more. Is there an explanation for this? thank you: select * from( SELECT x.id, x.title as Tag,z.url as Location, w.title as Name FROM moz_bookmarks x, moz_bookmarks y,moz_places z,moz_bookmarks w WHERE x.id = y.parent and y.fk = z.id and w.fk = z.id )where Tag like 'press_germany' – amdawb Sep 16 '18 at 20:40
0

My goal is to put aside tags corresponding to a project in stand by, and thus lighten my bookmarks ( 200 000 bookmarks for about 3000 tags, which shows that firefox is very robust). I can export these tags in csv format with DB Browser for SQLite, and get a xlsx file. this piece of code suits me perfectly: just the name and location of the tag.

select * from
( SELECT x.title as Tag, w.title as Name, z.url as Location 
FROM moz_bookmarks x, moz_bookmarks y,moz_places z,moz_bookmarks w 
WHERE x.id = y.parent and y.fk = z.id and w.fk = z.id )
where Tag == 'press_germany' and Name IS NOT NULL

thanks to the contributors.

amdawb
  • 3
  • 4