<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Michael Jay Lissner</title><link href="https://michaeljaylissner.com/" rel="alternate"></link><link href="https://michaeljaylissner.com/feeds/tag/database" rel="self"></link><id>https://michaeljaylissner.com/</id><updated>2014-06-18T00:00:00-07:00</updated><entry><title>Reworking the CourtListener Datamodel</title><link href="https://michaeljaylissner.com/posts/2014/06/18/reworking-the-courtlistener-datamodel/" rel="alternate"></link><updated>2014-06-18T00:00:00-07:00</updated><author><name>Mike Lissner</name></author><id>tag:michaeljaylissner.com,2014-06-18:posts/2014/06/18/reworking-the-courtlistener-datamodel/</id><summary type="html">&lt;p&gt;Brian and I have  been hard at work the past week figuring out how to make 
&lt;a href="https://www.courtlistener.com/"&gt;CourtListener&lt;/a&gt; able to understand more that one document type. Our goal
 right now is to make it possible to&amp;nbsp;add:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;oral arguments and other audio&amp;nbsp;content,&lt;/li&gt;
&lt;li&gt;video content if it&amp;#8217;s&amp;nbsp;available,&lt;/li&gt;
&lt;li&gt;content from &lt;a href="https://free.law/recap/"&gt;&lt;span class="caps"&gt;RECAP&lt;/span&gt;&lt;/a&gt;,&amp;nbsp;and&lt;/li&gt;
&lt;li&gt;thousands of ninth circuit briefs that Resource.org &lt;a href="https://law.resource.org/pub/us/case/ca9/"&gt;has recently&amp;nbsp;scanned&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The problem with our current database is that it&amp;#8217;s not organized in a way 
that supports linkages between content. So, if we have the oral argument 
and the opinion from a single case, we have no way of pointing them at each
other. Turns out this is a sticky&amp;nbsp;problem. &lt;/p&gt;
&lt;p&gt;The solution we&amp;#8217;ve come up with is an architecture like the&amp;nbsp;following:&lt;/p&gt;
&lt;p&gt;&lt;img alt="New Schema" src="https://michaeljaylissner.com/images/new-schema-design-compact_0.png" /&gt;&lt;/p&gt;
&lt;p&gt;(we also have &lt;a href="http://owncloud.freelawproject.org/public.php?service=files&amp;amp;t=76ef76ec69488fb72b4d96dba4809339"&gt;a more detailed version&lt;/a&gt; and &lt;a href="http://owncloud.freelawproject.org/public.php?service=files&amp;amp;t=62510f0282b06948e8c3d3b1e4946ec0"&gt;an editable version&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;And eventually, this will also have a Case table above the docket that 
allows multiple dockets to be associated with a single case. For now though,
that&amp;#8217;s moot, as we don&amp;#8217;t have anyway of figuring out which dockets go&amp;nbsp;together. &lt;/p&gt;
&lt;p&gt;The first stage of this will be to add support for oral arguments, 
since they make a simple case to work with. Once that&amp;#8217;s complete the next 
stage will be either to add the &lt;span class="caps"&gt;RECAP&lt;/span&gt; documents or those from&amp;nbsp;Resource.org. &lt;/p&gt;
&lt;h3 id="urls"&gt;URLs&lt;/h3&gt;
&lt;p&gt;Since this is such a big change, we&amp;#8217;re also taking this opportunity to 
re-work our URLs. Currently, they look like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;court&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;For&amp;nbsp;example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nl"&gt;https:&lt;/span&gt;&lt;span class="c1"&gt;//www.courtlistener.com/scotus/yjn/roe-v-wade/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;A few things bug me about that. First, it doesn&amp;#8217;t tell you anything about 
what kind of thing you can expect to see if you click that link. Second, 
the alpha-numeric &lt;span class="caps"&gt;ID&lt;/span&gt; is kind of lame. It&amp;#8217;s just a reference to the database
primary key for the item, and we should just show that value (in this case,
&amp;#8220;yjn&amp;#8221; means &amp;#8220;108713&amp;#8221;). To fix both of these issues, the new URLs will&amp;nbsp;be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opinion&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nl"&gt;https:&lt;/span&gt;&lt;span class="c1"&gt;//www.courtlistener.com/opinion/108713/roe-v-wade/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That should be easier to read and should tell you what type of item you&amp;#8217;re 
about to look at. Don&amp;#8217;t worry, the old URLs will keep working just&amp;nbsp;fine. &lt;/p&gt;
&lt;p&gt;And the rest of the new URLs will&amp;nbsp;be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;oral&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;argument&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;docket&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and&amp;nbsp;eventually:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;recap&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h3 id="api"&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;We expect these changes to come with changes to the &lt;span class="caps"&gt;API&lt;/span&gt;, 
so we&amp;#8217;ll likely be releasing &lt;span class="caps"&gt;API&lt;/span&gt; version 1.1 that will add support for 
dockets and oral&amp;nbsp;arguments. &lt;/p&gt;
&lt;p&gt;The current version 1.0 should keep working just fine, 
since we&amp;#8217;re not changing any of the underlying data, 
but I expect that it will have some changes to the URLs and things like 
that. I&amp;#8217;ll be posting more about this in the CourtListener dev list. 
as the changes become more clear and as we sort out what a fair policy is 
for the deprecation of old&amp;nbsp;APIs. &lt;/p&gt;</summary><category term="CourtListener"></category><category term="data modeling"></category><category term="database"></category></entry><entry><title>Changes and Plans at CourtListener.com</title><link href="https://michaeljaylissner.com/posts/2010/11/04/changes-and-plans-at-courtlistener/" rel="alternate"></link><updated>2010-11-04T23:30:21-07:00</updated><author><name>Mike Lissner</name></author><id>tag:michaeljaylissner.com,2010-11-04:posts/2010/11/04/changes-and-plans-at-courtlistener/</id><summary type="html">&lt;p&gt;A few weeks ago, we made a fairly major change at CourtListener.com to include 
&lt;span class="caps"&gt;ID&lt;/span&gt; numbers in all of our case URLs. This change meant that links that were 
previously like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nl"&gt;http:&lt;/span&gt;&lt;span class="c1"&gt;//courtlistener.com/scotus/Wong-v.-Smith/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Are now like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nl"&gt;http:&lt;/span&gt;&lt;span class="c1"&gt;//courtlistener.com/scotus/V5o/wong-v-smith/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Most of the old links should continue to work, but using the new links should 
be much faster and more reliable. The major difference between the two is the 
&lt;span class="caps"&gt;ID&lt;/span&gt; number, which is encoded as a set of numbers (in this case &lt;em&gt;V5o&lt;/em&gt;). This 
&lt;span class="caps"&gt;ID&lt;/span&gt; corresponds directly with the &lt;span class="caps"&gt;ID&lt;/span&gt; number in our database, aiding us greatly 
in serving up cases quickly and&amp;nbsp;accurately.&lt;/p&gt;
&lt;p&gt;Around the same time as this change, we added social networking links to all 
of our case pages to make them easier to share with friends and colleagues. 
These links use our new tiny domain, &lt;em&gt;http://crt.li/&lt;/em&gt;, and should thus be 
ideal for websites like Twitter or&amp;nbsp;Reddit.&lt;/p&gt;
&lt;p&gt;In the next few months we will be getting a major new server, and will be 
migrating our data to it. This will allow us to serve more data, 
and&amp;mdash;drum roll please&amp;mdash;will allow us to begin serving audio content 
on the site. That&amp;#8217;s right, in the next few months, we will begin getting oral 
arguments from the circuit courts, and will be serving it directly to you on 
the case&amp;nbsp;pages. &lt;/p&gt;
&lt;p&gt;We also have plans to revisit our search interface in order to add date 
filtering and query building so look for that&amp;nbsp;soon.&lt;/p&gt;
&lt;p&gt;As always, we welcome your feedback and support, so don&amp;#8217;t hesitate to get in 
touch with us if you have any questions or&amp;nbsp;suggestions.&lt;/p&gt;</summary><category term="CourtListener"></category><category term="Web Architecture"></category><category term="database"></category></entry><entry><title>Script to Clean Up F-Spot Database</title><link href="https://michaeljaylissner.com/posts/2009/10/14/script-to-cleanup-fspot-database/" rel="alternate"></link><updated>2009-10-14T00:30:12-07:00</updated><author><name>Mike Lissner</name></author><id>tag:michaeljaylissner.com,2009-10-14:posts/2009/10/14/script-to-cleanup-fspot-database/</id><summary type="html">&lt;p&gt;One of the more popular photo management applications for Linux is f-spot, 
but unfortunately it has a rather glaring bug. It uses a sqlite3 database 
internally to track which pictures you&amp;#8217;ve imported into it, 
what tags they have, etc. However, if you delete, move or rename any of the
files that f-spot is tracking, the next time you browse to that photo within f-spot, it will crash the program. It&amp;#8217;s annoying, and there&amp;#8217;s no particularly easy way to deal with it&amp;#8230;until&amp;nbsp;now.&lt;/p&gt;
&lt;p&gt;The script below simply iterates through all of the photos 
that are in f-spot&amp;#8217;s database, and checks to see if those photos exist on 
your hard drive. If you run it in demo-mode, it will show you which files 
look problematic, and if you run it in normal mode, 
it will delete those database entries so that your database is cleaned up 
(but not before backing up your database, just in&amp;nbsp;case).&lt;/p&gt;
&lt;p&gt;In my very limited testing, it works very well, any additional feedback or 
bug reporting is more than&amp;nbsp;welcome. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# A script to find missing files in the f-spot database, and then delete them.&lt;/span&gt;
&lt;span class="c"&gt;# At present these files crash f-spot. It&amp;#39;s frustrating as all hell.&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Welcome to the f-spot database cleaner. All the usual disclaimers apply, as you might imagine.&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;What would you like to do: &amp;quot;&lt;/span&gt; 
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;  1) Run in demo-mode &amp;quot;&lt;/span&gt; 
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;  2) Clean up your f-spot database&amp;quot;&lt;/span&gt; 
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;  3) Quit&amp;quot;&lt;/span&gt; 
&lt;span class="nb"&gt;read&lt;/span&gt; -p &lt;span class="s2"&gt;&amp;quot;Your choice: &amp;quot;&lt;/span&gt; choice

&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$choice&lt;/span&gt; in 
    1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;demomode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;;;
    2&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;demomode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;;;
    3&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;0;;
&lt;span class="k"&gt;esac&lt;/span&gt;

&lt;span class="c"&gt;# With that beginning stuff out of the way, let us do some functions&lt;/span&gt;
&lt;span class="c"&gt;# First, a function to gather the database contents and to print out the ones that are orphans&lt;/span&gt;

&lt;span class="k"&gt;function &lt;/span&gt;findAndFixOrphans &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# find our db, and set a var. Checking for XDG path first, since it&amp;#39;s the more recent location of the db&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -f &lt;span class="nv"&gt;$XDG_CONFIG_DIR&lt;/span&gt;/f-spot/photos.db &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="c"&gt;#checks if the $XDG_CONFIG_DIR variable is in use&lt;/span&gt;
    &lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;DBPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$XDG_CONFIG_DIR&lt;/span&gt;/f-spot/photos.db
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -f &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.config/f-spot/photos.db &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="c"&gt;#uses the default $XDG location, if that&amp;#39;s being used.&lt;/span&gt;
    &lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;DBPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/.config/f-spot/photos.db
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -f &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.gnome2/f-spot/photos.db &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="c"&gt;#uses the old location of the DB, if the former aren&amp;#39;t in use.&lt;/span&gt;
    &lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;DBPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/.gnome2/f-spot/photos.db
    &lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="k"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Error: Could not find database. Damn.&amp;quot;&lt;/span&gt; 
        &lt;span class="nb"&gt;exit &lt;/span&gt;1
    &lt;span class="k"&gt;fi&lt;/span&gt;

    &lt;span class="c"&gt;# Select the filenames, and put them in a variable.&lt;/span&gt;
    &lt;span class="nv"&gt;filenames&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;sqlite3 &lt;span class="nv"&gt;$DBPATH&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;SELECT URI FROM PHOTOS&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;filenames_versions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;sqlite3 &lt;span class="nv"&gt;$DBPATH&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;SELECT URI FROM PHOTO_VERSIONS&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Chomp off the first instance of file://, and replace the rest with newlines.&lt;/span&gt;
    &lt;span class="nv"&gt;filenames&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$filenames&lt;/span&gt; | sed &lt;span class="s1"&gt;&amp;#39;s/file:\/\///&amp;#39;&lt;/span&gt; | sed &lt;span class="s1"&gt;&amp;#39;s/file:\/\//\n/g&amp;#39;&lt;/span&gt;  &lt;span class="k"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;filenames_versions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$filenames_versions&lt;/span&gt; | sed &lt;span class="s1"&gt;&amp;#39;s/file:\/\///&amp;#39;&lt;/span&gt; | sed &lt;span class="s1"&gt;&amp;#39;s/file:\/\//\n/g&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$demomode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;then            &lt;/span&gt;
&lt;span class="k"&gt;        while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; -r line
        &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="c"&gt;# Decode the filename&lt;/span&gt;
            &lt;span class="nv"&gt;decodedLine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;quot;${line//\%/\\x}&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; ! -f  &lt;span class="s2"&gt;&amp;quot;$decodedLine&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; 
            &lt;span class="k"&gt;then&lt;/span&gt;
                &lt;span class="c"&gt;# If the file doesn&amp;#39;t exist, we output the filename, if in demomode, or we fix it if we are not in demomode.&lt;/span&gt;
                &lt;span class="nb"&gt;echo&lt;/span&gt;  &lt;span class="s2"&gt;&amp;quot;Errant record found in the photos table: $decodedLine&amp;quot;&lt;/span&gt;
            &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;        done&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;$filenames&amp;quot;&lt;/span&gt;

        &lt;span class="c"&gt;# We do the same for the photo_versions table&lt;/span&gt;
        &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; -r line
        &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="c"&gt;# Decode filename&lt;/span&gt;
            &lt;span class="nv"&gt;decodedLine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;quot;${line//\%/\\x}&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; ! -f &lt;span class="s2"&gt;&amp;quot;$decodedLine&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;then&lt;/span&gt;
                &lt;span class="c"&gt;# If the file doesn&amp;#39;t exist, we output the filename&lt;/span&gt;
                &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Errant record found in the photo_versions table: $decodedLine&amp;quot;&lt;/span&gt;
            &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;        done&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;$filenames_versions&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="c"&gt;# We backup the database, and make the correction&lt;/span&gt;
        cp &lt;span class="nv"&gt;$DBPATH&lt;/span&gt; &lt;span class="nv"&gt;$DBPATH&lt;/span&gt;.&lt;span class="sb"&gt;`&lt;/span&gt;date -I&lt;span class="sb"&gt;`&lt;/span&gt;.bak
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; -eq 0 &lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;then&lt;/span&gt;
            &lt;span class="c"&gt;#The backup worked, tell the user.&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Your database has been backed up to $DBPATH.`date -I`.bak&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="k"&gt;            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Error backing up your database.&amp;quot;&lt;/span&gt;
            &lt;span class="nb"&gt;exit &lt;/span&gt;3
        &lt;span class="k"&gt;fi&lt;/span&gt;

        &lt;span class="c"&gt;# First we do the photos table&lt;/span&gt;
        &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; -r line
        &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="c"&gt;# Decode the filename&lt;/span&gt;
            &lt;span class="nv"&gt;decodedLine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;quot;${line//\%/\\x}&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; ! -f &lt;span class="s2"&gt;&amp;quot;$decodedLine&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;then&lt;/span&gt;
                &lt;span class="c"&gt;# Do some sql here.&lt;/span&gt;
                &lt;span class="nv"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;file://${line}&amp;quot;&lt;/span&gt;
                &lt;span class="nb"&gt;echo&lt;/span&gt; -n &lt;span class="s2"&gt;&amp;quot;Deleting URI $line from the database table photos...&amp;quot;&lt;/span&gt;
                sqlite3 &lt;span class="nv"&gt;$DBPATH&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;DELETE FROM PHOTOS WHERE uri = &amp;#39;$foo&amp;#39;&amp;quot;&lt;/span&gt;
                &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;done.&amp;quot;&lt;/span&gt;
            &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;        done&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;$filenames&amp;quot;&lt;/span&gt;

        &lt;span class="c"&gt;# Then we do the photo_versions table&lt;/span&gt;
        &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; -r line
        &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="c"&gt;# Decode the filename&lt;/span&gt;
            &lt;span class="nv"&gt;decodedLine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;quot;${line//\%/\\x}&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; ! -f &lt;span class="s2"&gt;&amp;quot;$decodedLine&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;then&lt;/span&gt;
                &lt;span class="c"&gt;#Do some sql stuff&lt;/span&gt;
                &lt;span class="nv"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;file://${line}&amp;quot;&lt;/span&gt;
                &lt;span class="nb"&gt;echo&lt;/span&gt; -n &lt;span class="s2"&gt;&amp;quot;Deleting URI $line from the database table photo_versions...&amp;quot;&lt;/span&gt;
                sqlite3 &lt;span class="nv"&gt;$DBPATH&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;DELETE FROM PHOTO_VERSIONS WHERE uri = &amp;#39;$foo&amp;#39;&amp;quot;&lt;/span&gt;
                &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;done.&amp;quot;&lt;/span&gt;
            &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;        done&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;$filenames_versions&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;$demomode&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Great. Proceeding in demomode.&amp;quot;&lt;/span&gt;

    findAndFixOrphans

    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Demomode successfully finished. Exiting.&amp;quot;&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;0;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;$demomode&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Great. Cleaning up your database.&amp;quot;&lt;/span&gt;

    findAndFixOrphans

    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Database cleaned successfully.&amp;quot;&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;0;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="k"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Something strange happened. See the script for details. Exiting.&amp;quot;&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;2;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</summary><category term="sqlite3"></category><category term="f-spot"></category><category term="database"></category><category term="bash"></category></entry></feed>