Which Platform for RootsMagic Utilities? #application #developer #visualc

This page is intended to stimulate some discussion about developing utilities for RootsMagic in a high level programming language. Please add your thoughts. Would you be interested in:

  • using utilities that do things RootsMagic does not currently do?
  • developing such utilities?
  • testing?

Development Platform?

I had been setting up an old Borland Delphi 4 with DiSQLite3, thinking it was time to move some of the SQlite scripts into some kind of menu driven collection of utilities to make them more amenable to persons flummoxed by working directly with queries. I had just compiled a fake RMNOCASE extension for SQLiteSpy on it which would also work with DiSQLite3, and thought that this would be a logical platform because RootsMagic is also developed on contemporary Delphi and DiSQlite3.

Then along came Steve Turley who started the ball rolling with RmSplit on the page SplitTree, using Visual Studio C# 2010, because, as he said:

I chose Visual C# because I find it's a quicker development environment for projects like this.
The advantage of C++ is that it has a more direct connection to the base sqlite library which
is written using unmanaged code. For other projects, C++ tends to be more portable, but an
application written specifically for Windows like this one is tied to a single platform anyway.
 
Mostly, it's a personal preference. I am a physics professor and do a lot of research work with
students. I have found that I can bring them up to speed faster on C# programming than C++ so I
tend to gravitate towards that for simple windows programs.
 
That said, if I was writing a big production code or if performance were at a premium, I'd
probably use C++.

I installed Visual C# 2010 Express and Steve’s project package and was able to generate my own version of RmSplit with minor changes in the user interface. I’ve been a program ‘dabbler’ since before DOS, just enough to whet my appetite and maybe accomplish something odd for work or play but never on an ongoing basis. Never got into object-oriented programming – I’m a procedural guy and not sure if C# is the way to go for me.

Another option for me is Tcl/Tk. Tcl was used to develop SQlite and I have some passing acquaintance with it from about a decade ago. And it’s totally free, unlike DiSQLite3 and Delphi, and, for that matter, anything above the Express level in Visual Studio products. On opening Visual C# Express, it says it is for Evaluation Purposes Only; I cannot find the EULA so am unsure of the restrictions, and am seeing a 28 day countdown which suggests that there may be features that get turned off when that period expires.

PHP has SQLite built-in, is well suited for server-side web applications, and is free. Never used it and don’t know how suited it is to a stand-alone app.

And I just had a brief look at SQLite for Excel. Took me a while to understand what the sample demo was doing. Basically adds VBA macros to a workbook via which a SQLite database can be worked on. The demo seemed pretty slow as does RmSplit so I wonder about the number of layers between the user and the data.

The worrisome thing is the learning curve on any of these. Peter Norvig, author of Teach Yourself Programming in Ten Years says his “recommendations for a first programming language would be Python or Scheme. SQlite is included in recent Python distributions; links for Scheme wrappers on sqlite.org are dead.

Peter also advises to Use your friends, i.e., use what they use as there is greater strength in a community. If you are interested in collaborating on the development of utilities for RootsMagic, what would you use? What are you using?

(Added by Jerry Bryan): I’ve been following this discussion with great interest. I agree with the opinion that as long as SQLite remains unbundled where a user has to download an SQLite manager and also download an SQLite script and figure out how to operate the two together, SQLite scripts will only reach a very small niche of the RM4/5 user base. Being able to download a bundled program which is fully self contained (an EXE file, if you will) should enable useful utility functions to reach a much greater audience than the unbundled approach will ever reach. So I’m excited about the possibility of bundled utility applications.

I’m an old C/C++ programmer from way back and I know nothing about C# except in as much as C# may have common roots in C. I’m not interested in advocating for C/C++ as the platform of choice, but I am interested possibly in writing a RM4/5 utility application myself in C/C++. And I’m interested in seeing a “baby steps” example of what’s required. Exactly what C/C++ library for SQLite do I have to download and from where? How do I do the compile? And would it be possible to have a really simple examplar to look at, even if it were written in C# instead of C++? For example, I would love to see a C++ or a C# program that would do something so simple as SELECT * FROM NameTable, and gather up and print the results. In other words, the example program would need no real logic at all. I would just like to see how to put the pieces together. If I could get even one such simple program to compile and execute, I think I could easily go from there to developing much more complicated and useful applications.

(Added by Steve Turley)
Here is an example in C++ to supplement the C# version posted elsewhere. My two easy choices are using gcc under linux or Visual Studio. I’ll start with Visual Studio since I’m guessing an RM user is probably running on a Windows platform. By the way, there is one issue that doesn’t show up in a query like SELECT * FROM NameTable. If you want to modify a table in the database, you may have to worry about the collation. Many of the tables are index with an RMNOCASE collation. I’ll save that issue for a little later.

#include <iostream>
#include "sqlite3.h"
 
using namespace std;
 
static int callback(void *unused, int argc, char **argv, char **colName){
    for(int i=0; i<argc; i++){
        cout<<colName[i]<<" = "<< (argv[i] ? argv[i] : "NULL") <<endl;
    }
    cout<<endl;
    return 0;
}
 
int main(){
    cout<<"Example RM Database Queryn";
    sqlite3 *db;
    int rc = sqlite3_open("test.rmgc", &db);
    if(rc){
        cerr<<"Error opening database filen";
        return 1;
    }
    cout<<"Database table opened successfullyn";
    const char *sql = "SELECT * FROM NameTable LIMIT 20";
    char *error=NULL;
    rc = sqlite3_exec(db, sql, callback, NULL, &error);
    if(rc){
        cerr<<"Error executing queryn";
        sqlite3_free(error);
    }
    sqlite3_close(db);
    system("PAUSE");
}

To set this up with the sqlite3 library you need to following these steps:

  1. Create the above program as an unmanaged Win32 console application.
  2. Download the source code for the sqlite library at http://sqlite.org/sqlite-dll-win32-x86-3070900.zip
  3. Unzip this file to the course code directory for the above program. (An easy way to find this directory is to right click on the tab for this code and choose open containing folder.)
  4. Add the sqlite3.def and sqlite3.dll to your project directory. (Right click on the project name and choose Add/Existing item…)
  5. Create sqlite3.lib by executing the VS command LIB /DEF:sqlite3.def.
  6. Add sqlite3.lib and sqlite3.def to the list of library files and Module definition files used by the linker.
    1. Right click on the project name and choose properties.
    2. Select the Input item in the Linker Group.
    3. Add sqlite3.lib to the list of files with a terminating semicolon.
    4. Add sqlite3.def as the Module Definition file.
  7. Download the file http://sqlite.org/sqlite-dll-win32-x86-3070900.zip
  8. Unpack the file sqlite3.h and put it in the header folder for the project.

Here is a zip file with my project in it as I built it. RmCppConsole.zip

(Added by Jerry Bryan)
First a procedural question/comment: Simply editing one of the wiki pages seems not to be the best way to carry on what is essentially a threaded conversation. Is there a better way to carry on such conversations within the confines of the wiki architecture? Like most people, I’ve read wikis for years, but this RM/SQLite wiki is the first time I’ve ever joined a wiki and posted to it. I’m more familiar with threaded conversations in the context of forums and bulletin boards, blogs, and even old fashioned E-mail.

Second: Much thanks to Steve Turley for posting the sample code. It’s exactly what I was looking for, even down to the fact that it’s a console application instead of a Windows application. I’m a computer science guy, but I do IT for a living and seldom have an opportunity to do real computer science. I do teach a course occasionally, but it’s been several years since I’ve even had time to do that. Being a college administrator is not as much fun as teaching or as doing real computer science. So developing some object oriented code on sort of a hobbyist basis sounds like a lot of fun.

Third: As to my experience with C++, it’s strictly as a hobbyist. Our college still uses C for its intro and data structures classes, which are the ones I usually teach if I teach. The question of “first language to teach” has long been a hot topic of debate among computer science, and our college has chosen to stick with a procedural language as the “first language to teach”. I find that my C students always ask what the difference is between C and C++. It’s a curiously difficult question to answer in a way that’s both brief and meaningful. You really need to experience object oriented programming by doing it, and most people learning an object oriented language have a major “aha moment” when they “get it” about what object oriented programming really is. Having said that, I’ve probably written about 40,000 or 50,000 lines of C++ code in the last 10 or 15 years (just for fun). Until very recently, I’ve used the (now) very old Borland C++ compiler version 5. Serendipitously, I’ve just started the switchover to Visual Studio Express. I haven’t decided yet if the Express version is good enough, or if I’m going to need to upgrade to a professional version. For my ongoing projects that are not RM/SQLite related, I still don’t need anything except for console mode, but I’m eventually going to need huge data spaces and 64 bit operation. It’s not clear to me if Visual Studio Express will do 64 bit operation, or if it’s limited to 32 bit. Of course, 32 bit is fine for any RM/SQLite needs. And by the way and in case anybody is interested, my big C++ project for years has been the investigation of the mathematics of Rubik’s cube. There are many interesting problems that are computationally intensive and that sometimes run for months on a PC.

Discussions & comments from Wikispaces site


romermb

VB.net

romermb
08 January 2012 05:25:52

What would be the advantages and disadvantages of VisualBasic.net?


rsturley

rsturley
08 January 2012 05:38:42

VB.net would have the same interface to SQLite and WindowsForms environment as C#. Personally, I think the C# environment is richer and better suited to collaborative projects (easier to define and enforce interfaces using classes). However, the community of programmers with an interest in this project may have a larger group with VB.net background. The end users of the utilities probably won’t see much difference in applications programmed either way.


rsturley

Bundled Utilities

rsturley
08 January 2012 05:34:22

The idea of bundled utilities intrigues me. My RmSplit was a bit of an experiment thinking about a larger package of utilities. Here are my comments on some of your ideas on the best development language.

C#: a proprietary environment that only works on Windows. It sounds like Bruce is working on expanding RM to be available on several mobile platforms and Mac OS. In principle, we could extend a project to work on other platforms using mono, but that would probably not be ideal.

Python: I’ve tried some of this kind of work on python before. It is a great tool for one-up kinds of things, but it doesn’t have strong tools for a GUI that would be a good interface for non-experts.

PHP: I have used this as a web programming language and a stand-along scripting language. I think I like this suggestion the best of the ones you suggested in your page. One nice thing about it is that the project could be hosted “in the cloud” and we don’t have to worry about distributing or updating the code. We could have a web-based package that incorporated an organized set up the SQL scripts appearing in this wiki process them on the server rather than the user’s local computer. I don’t think the community of users is so big that it would be a processing problem, but we could try it on a small set of scripts and see how much traffic we get.

Java (one you didn’t mention): This would either be stand-alone code (more portable than C# probably) or server based (.jsp files which similar organization to PHP). If we go with a cloud-based solution, I prefer PHP over java because server maintenance is a bit easier and servers supporting PHP are more widespread than those supporting jsp.

Anyway, if you decide to support a language and platform I have experience with I’m willing to help.


LessTX

LessTX
09 January 2012 18:26:47

Just for testing and looksee:
https://leslietest.slsapp.com/
https://leslietest.basecamphq.com/

The first is a springloops site, and it has a link of some kind to basecamp, so I created one of those, too.

That could be a place for us to start out…
the springloops site for the codebase stuff, and the basecamp for the visual planning, conversations, ideas, chat, milestones, etc

Are those sites and utilities that you think folks would find easy enough to use?


ve3meo

RMNOCASE

ve3meo
25 January 2012 18:45:03

Blundering around in Steve’s RMsplit project, trying to learn the rudiments of C#, OOP, Visual Studio and wanting to leap ahead to something useful, I did manage to run the SQLite Integrity Check with the fake RMNOCASE Steve came up with. The outcome is not good. It reports many index errors on databases that RM5’s integrity check reports as OK, just as does SQLiteSpy with the fake extension built with Delphi. The latter has many more reported discrepancies and the two do agree on most of those reported by C#.

This means that, until we can use the identical collation sequence as in RM, procedures that modify data so collated should be precluded from being used on RM4 databases and that, for RM5 databases, a strong warning that there may be unanticipated consequences and advise the user to use the RM5 Rebuild Indexes feature after any such changes by the utility.


ve3meo

Inline comment: “I would love to see a C++ or a C# program that would do something so simple as SELECT * FROM NameTable”

ve3meo
04 September 2018 03:39:33

ve3meo Jan 9, 2012

Jerry, download the project file that Steve posted on SplitTtree and look at RmSplitForm.cs for examples of the query. He also includes in the project the necessary SQLite files.
rsturley Jan 9, 2012

Jerry,

I created a c+ example program that does the simple thing you asked about (SELECT * FROM NameTable) using Visual C++. To keep it simple I didn’t put in any GUI stuff, but rather chose a simple console application. The example and a brief explanation of the process of creating it are in the wiki page.


ve3meo

Inline comment: “Is there a better way to carry on such conversations within the confines of the wiki architecture?‍”

ve3meo
04 September 2018 03:41:10

ve3meo Jan 12, 2012

Yes! Each wiki page has a Discussion “forum”, i.e., a page under the wiki page where you can post a topic (really any topic but preferably one related to the subject of the wiki page) and a threaded (sort of) discussion can flow. By sort of threaded, I mean that all posts under a given topic can be found under that topic but you cannot see which post a post has replied to and the reply system includes no quotes. For a straight serial conversation it’s fine. To open the Discussion page, you click on the double bubble button on the wiki page.

A variant of the Discussion page is to comment on selected text on the wiki page itself, as I am doing here. You have to Edit the page, highlight the text to comment on, click the Comment bubble button and write your comment in the form. The comment also appears on the Discussion page under the topic which is the highlighted text and replies thereto automatically show up as comments on the wiki page itself. To see the comments on the wiki page, you click on the button with the single bubble on the wiki page.
ve3meo Jan 12, 2012

OOps, got the way the topic works wrong, as you can see… The highlighted text on the wiki page is quoted in the post seen on the Discussion page; the topic of the post is “Comment added:”+ first few words of first sentence of comment.

Bundled Utilities – Example content

As an external utility for the RootsMagic genealogy program, what would it do, how would it look?

Initially, it would take the many tweaks and modifications discussed on this site and roll them into a format that is usable for the average RM user.

Rationale

There are a lot of general database cleanup or modification items that users want to be able to do, but that RootsMagic doesn’t do on its own. Some of these things RM may do in the future, some maybe not, but since it’s possible to modify the database itself, it can be done. Users don’t know or need to care about the database structure or the commands needed to get it done. In order to make the many wonderful things on this site more widely used (and make maximum use of the efforts folks have gone into to develop and explain these things) a layer needs to be put on top of the SQL Queries, so that the words SQL and Query are really not even mentioned.

Example from TMG Utility

The best way to ensure success is to look at how others have achieved it. TMG is a genealogy program much like RM, it’s based on FoxPro, and there’s a wonderful utility program for it. Many TMG users benefit from the TMG Utility program, and very few know or care about FoxPro.

The website for the utility is here: http://www.johncardinal.com/tmgutil/

Screencast

I have made a screencast of the utility, showing the program’s structure, the options provided to the users, and I’ve added notes of some of the parts of the program. It’s a 5 minute screencast, found here:
http://screencast-o-matic.com/watch/clV6cZxnb (apparently deleted, accessed 2019-01-26)

You can, I think, watch the screencast via this frame, but for my notes, you probably need to go to the website itself.

Program Structure

The expanding folder view on the left is a very common, easily understood paradigm, and automatic “categorization” of all of the options. I highly recommend that RMutils use the same concept. The structure of TMG Utilities echoes the DBF files that are modified, for RMutils we’d use the database tables.

The function windows are pretty clean and straightforward.

The help “file” is an on-disk version of the program’s website, I’d be tempted to suggest making our help file go to the live website itself rather than on disk files. In that way, the help system is always as up-to-date as possible.

The program’s website, is, IMO, NOT a great example to copy.

Example from LTools

(added by ve3meo)
LTools is to Legacy Family Tree as TMG Utility is to The Master Genealogist, filling some needs that the main database program does not satisfy. Independently developed, it accesses the Legacy JET database (JET underlies Microsoft Access). Unlike the TMG Utility, it exposes the user to SQL queries, even supports user defined SQL queries, at least in the Deluxe (paid license) version. The Standard version is free. I downloaded the free version of LFT and LTools for the purpose of reviewing primarily the latter, insofar as we might also learn something from it that might be applicable to the rmutil design.

Screencast


http://screencast-o-matic.com/watch/clVXqpx6g (black screen, accessed 2019-01-26)

Program Structure

LTools also uses the expanding list feature. The grayed out area on the right in the Standard edition which shows the inaccessible Deluxe features is likely merged with the standard list in the Deluxe version, given the common root names.

Help is solely on-line.

As a SQLite user, I like the idea of being able to have an interactive SQL screen in the utility – I have asked for the same to be provided in RootsMagic itself. LTools appears to provide a way of storing and recalling user defined SQL queries – cool!

Discussions & comments from Wikispaces site


LessTX

Interface and Program Structure

LessTX
12 January 2012 18:40:56

There’s a lot to like in LTools. I like the idea of a “Standard and Advanced Mode” interface option. The help website looks superior, but reinforces the concept that “help on the web” is the way to go.

Standard doesn’t use the word query or SQLite and keeps things in plain English.

Advanced mode would enable the menu options to show, save, and modify the queries themselves.

Then also having more complex things be part of a paid product is a good idea, but allocating half of the app window doesn’t make a lot of sense. Having them as disabled items on the single list makes more sense to me.


ve3meo

Comment: “The expanding folder view on the left is a very common, easily understood paradigm…”

ve3meo
03 September 2018 20:00:25

ve3meo Jan 10, 2012

Nice! I have been grouping the existing SQLite queries to relate to the RM menu structure as that might lead to an easy way for users to find relevant ‘potions’. But some queries don’t readily fit or could tie to more than one category. In some respects, categorising by table name might be easier but many use multiple tables. There’s lots to play with, here. Thanks for the walkthrough and your comments.

Bundled Utilities – Groupings #application

This page is intended to group existing SQLite queries and future functions
under a menu structure that parallels that of RootsMagic itself, with the
idea that similar naming, order and, possibly, locations on screen may
facilitate user navigation to the utilities most relevant to their area of
interest or concern. This is a first draft.
RMutil-Menu.xlsx

Rmutils (working name) January 10, 2012
Main Menu 5:55 PM
SQLiteToolsForRootsMagic query or other description
Sort Main Sub1 Sub2 Query Name Description Page Comment
1

File

1.1 File Open Open Windows Explorer browser on *.rmgc files. Get database version, possibly do SQLite Quick Integrity Check
“PRAGMA quick_check(integer);”
1.2 File Open Recent
1.3 File Search for Files
1.4 File Close
1.5 File Copy
1.5.1 File Copy All
1.5.2 File Copy Less People CustomDatabaseShell Makes an empty Master from current database, preserving custom
fact types and source templates, Places, Master Sources and
associated Repositories and Addresses, and Place/Source Media
Depopulate
but keep Customs, Places, Sources
1.5.3 File Copy To vanilla DB3 RM#_CREATE_as_DB3_NOCASE | RM#_Copy_Data_to_DB3_NOCASE Clones a RM4/5 database without the RMNOCASE collation so that
we’re free to do what we want to the data. Even works with RM but it
might trip up on non-English alphabets.
Convert
Database to NOCASE
1.6 File Database tools…
1.6.1 File Integrity check Check RootsMagic Database Integrity Explains why an integrity check is needed and how, using PRAGMA
quick_check.
Check
RootsMagic Database Integrity
1.6.1 File Integrity check PRAGMA integrity_check(integer);
1.6.2 File Reindex REINDEX
1.6.3 File Clean TBD Deletes unused rows from tables as reported by RMGC_Properties.
May need checkbox options to select what tables are cleaned. RM4
& 5 are different
Conceivably, Properties & Clean could be one form with
checkboxes for tables that have unused rows & a Clean button
1.6.3a File Clean Delete Phantom Citations Deletes citations of non-existent Sources from database that
manifest themselves in the Edit Persons screen as a citation
(counted and checkmarked) but return nothing when opened.
Delete
Phantom Citations – Query
1.6.4 File Compact VACUUM
1.7 File Export TBD possible route to a control of Fact settings for GEDCOM export
1.8 File Backup…
1.8.1 File Database file only
1.8.2 File Include media RMfullbackup.bat Backs up the database file along with all the media files
referenced by it to one file. Uses the command versions of SQLite3
(free), WinRAR ($fee) and 7-Zip (free). The 7-Zip version produces a
.rmgb file that RootsMagic can restore, media and database.
Backup
Media with Database – RAR
1.8.2 File Include media RMfullbackup.bat Backs up the database file along with all the media files
referenced by it to one file. Uses the command versions of SQLite3
(free), WinRAR ($fee) and 7-Zip (free). The 7-Zip version produces a
.rmgb file that RootsMagic can restore, media and database.
Backup
Media with Database – 7Zip
If there is Backup, should there be Restore from within Rmpotions?
1.9 File Properties Database Properties Reports in a list most of the values found in RM4’s File >
Properties report; results can be exported to a file.
Database
Properties List – Query
1.9 File Properties RMGC_Properties As ‘Database Properties’ but with more detail and pointing out
possible problem areas
RMGC_Properties
– Query
Variant for RM5 TBD
1.9 File Properties RMGC_TablesRowCount Lists count of rows in each table — If not 22 tables listed,
database has corruption
RMGC Tables
Row Count
1.A File Exit
2

Edit

2.1 Edit Person
2.1.1 Edit Person Birth Year BirthYearMisMatch Lists Individuals whose Birth Year from NameTable does not match
that of the date for their Birth fact.
Birth Year
Mis-Match
2.1.2 Edit Person Death Year DeathYearMismatch Lists Individuals whose Death Year from NameTable does not match
that of the date for their Death fact.
Death Year
Mismatch
2.1.3a Edit Person Set Living SetLivingFlag Another version of a Set Living query. Another
version of a Set Living query
2.1.3b Edit Person Set Living SetLivingFlag A discussion of queries that can modify the Living flag. Set Living Flag
2.1.4 Edit Person Same day sort order SortDateSameDayOrder | SortDateSameDayOrderCustom Re-orders all same day events of limited types to a natural order,
e.g., Birth before Death
Dates –
Same Day Sort Order
2.1.5 Edit Person Copy fact to group CopyFact2Group Copies a fact/event for a person to a Named Group of persons,
along with the Sources but not the Media for the Fact.
Copy Fact to
Group
2.1.6 Edit Person Copy RIN to REFN CopyRINtoREFN Variant of CopyFact2Group that copies a REFN fact to a group,
substituting the target persons’ PersonID’s or RIN for that of the
source person.
Copy RIN to REFN
2.1.7 Edit Person Convert sharable facts SharableFacts2 | SharableEvents-Convert List and convert events having key properties in common to shared
events. Especially useful on imports from Legacy Family Tree in
which events were copied to multiple persons.
Sharable
Events – Find and Convert to Shared
3

Lists

3.1 Lists Source List
3.1.1 Lists Source List Source List Source List About as close as we can get to a RM4 Source List Report presented
in tabular form with which the results can be sorted and filtered
with relative ease.
Source List Query
3.1.2 Lists Source List Source Details Source Detail View (Parsing XML) Lists Source Names along with Source Detail field names;
illustrates principles applicable to Master Source fields and other
XML-like columns.
Source
Detail View (Parsing XML)
3.1.3 Lists Source List Citations AllCitations Lists all citations in the database from which citations of
non-existent sources (‘phantoms’) and citations for non-existent
events or persons (‘headless’) can be found, along with other useful
information such as all citations per source.
All Citations –
Query
3.1.3 Lists Source List Citations AllCitations+Dupes Lists all source names cited for a person in descending order of
the count of duplicate citations – a help in finding and resolving
duplicate citations after merging.
All
Citations & Dupes Count – Query
3.2 Lists To-Do List
3.2 Lists To-Do List To-Do (was To-Do4Persons) Lists uncompleted To Do tasks for Individuals, Families and
General; can be readily modified to filter or sort by surname,
priority, repository, etc.
RM4 To Do List
3.3 Lists Research Manager
3.4 Lists Media Gallery
3.4.1 Lists Media Gallery Duplicates MediaRepair Series of queries to list duplicate media file names in the Media
Gallery and list duplicate links to items in the Gallery. Repairs a
specific case of duplicate file names as an example; repairs all
cases of duplicate links.
Media Repair
Queries
Needs rev for RM5
3.4.2 Lists Media Gallery List uses Media Users List Complete listing of all users of media in the Gallery, more
complete and navigable than what is provided in RM 4.1.2.1
Media Users
List Query
Needs rev for RM5
3.4.3 Lists Media Gallery Files usage ScrapBookFilesStatus Lists files under the RM Multimedia default folder and flags those
used by the RM database; helps to ensure that files are used.
Scrapbook
Files Status
3.5 Lists Address List
3.5.1 Lists Address List Blank Names blankname_in_addresslist List Persons with Blank Names in the Address List — (a fault that
may occur in a GEDCOM import).
Four Little
Queries
3.6 Lists Repository Manager
3.7 Lists Correspondence List
3.8 Lists Place List
3.8.1 Lists Place List Unused Places UnusedPlaces List of unused Places Four Little
Queries
3.8.2 Lists Place List Place Details PlacesDetails Lists Places having Place Details Four Little
Queries
3.8.3 Lists Place List Convert to Place Details Places to Place Details Conversion Combo of SQLite queries and RM4 edits of Place List beats having
to edit every fact/event to split a Place into Place and Place
detail; otherwise, wait for the RootsMagician!
Places
to Place Details Conversion
3.8.4 Lists Place List Place Details with Facts FactsHavingPlaceDetails3 Returns all Places with Place Details and the Persons or Families
(couples) and their Facts, including Shared events, using the Place
Detail.
Facts
Having Place Details – Query
3.9 Lists Fact Type List Manage, save, apply Fact settings for Export, Reports, Privacy
3.A Lists Source Templates
3.A.1 Lists Source Templates Sources by Template SourceTemplateListWithCitationDetails2.sql Lists Sources associated with Source Templates, as well as an
extension to Citation details. Free-Form templates are excluded
since they’re not included in SourceTemplateTable.
Source
Template List – Query
3.A.2 Lists Source Templates Make Editable SrcTmpltsConvert Converts Sources using uneditable, built-in templates to using
editable copies.
Source Templates
3.A.3 Lists Source Templates Revert to Built-in SrcTmpltsRevert Reverts Sources modified by SrcTmpltsConvert to using uneditable,
built-in templates.
6

Search

6.1 Search Name NameFind Produces a list of names that match or sound like specified names,
similar to RM4’s NameFind.
Name Find query
6.2 Search Surname selected_surnames List Persons with specified Surnames. — Example of creating a SQL
View or Virtual Table and the explicit use of COLLATE NOCASE to
override the RMNOCASE collation defined for certain fields and
embedded in the RootsMagic application.
Four Little
Queries
6.3 Search Search & Replace Search&Replace Discussion and examples of how you can search (filter) using any
SQLite manager and replace found values with revised ones using
SQLiteSpy.
Search &
Replace
7

Reports

7.1 Reports Format
7.1.1 Reports Format Paragraphing Paragraph-Strip | Paragraph-Add Removes CR/LF characters around custom fact sentences and
person/family/alt name/fact notes and adds CR/LF pairs to ends of
notes except the last, for first cut batch paragraphing.
Paragraphing
7.1.2 Reports Format Strip footnote line feeds Fix Extra Line Feeds in Footnote This query strips extraneous Carriage Returns from the end of the
Footnote sentence template for the Source Template “Vital Records
(state-level, online derivatives)” which cause unwanted white space
in reports.
Source Templates
7.2 Reports My Lists
7.2 Reports My Lists All facts AllFacts4Persons List all the Individual, Family and Shared Facts/Events for all
persons in a database. A complex query using UNION ALL, COUNT() and
GROUP BY, constants and NULL to assemble multiple SELECTs in one big
result.
Pulling
Together All the Events for An Individual
7.2 Reports My Lists Begatters PersonsBegatChildren An optional extension to AllFacts4Persons or standalone. Having a
Child as an event for the Father and the Mother.
Births
of children as facts
7.2 Reports My Lists Direct Ancestors Ancestors Lists all the ancestral lines for a given RIN Ancestors Query
7.2 Reports My Lists DNA DNA_mtDNA_locationslist | DNA_Y-STR_markerslist Two queries that list the test results in a format suitable for
easy review and copying and pasting into other applications.
RM4.1.1.4 provides no DNA report.
DNA Test
results list
7.2 Reports My Lists Facts shared with persons in database People Who Share a Fact with a Principal Lists people who share a fact with a Principal, as well as
relevant fact and Principal information.
People
Who Share a Fact with a Principal List – Query
7.2 Reports My Lists Facts shared with persons NOT in database People Who Share a Fact with a Principal, But Who Are Not in a
Tree in the File
Lists people who share a fact with a Principal, but who aren’t in
a tree in the database file, as well as relevant fact and Principal
information.
People
Who Share a Fact with a Principal, But Who Are Not in a Tree in
the File List – Query
7.2 Reports My Lists Geo-Lifelines Geo-Lifelines Have you ever wished to be able to look at all the facts in your
family tree database that happened within a day’s horseride of a
certain location? This adaptation of the LifeLines query helps you
view your events for any geographic area in addition to looking at
the lifeline of any person in your database.
Geo-Lifelines
Query
7.2 Reports My Lists LifeLines LifeLines Lists all events for all persons whether in a database tree or
not, including shared facts, date, fact detail, site and place,
MRIN, other parties, and duplication indicator. Sorted by RIN and
Sort Date. With the right SQLite manager, can filter results for one
person.
LifeLines – Query
7.2 Reports My Lists Map Events (KML) MapEvents-KML This query helps you plot events from your RootsMagic database on
Google Maps, Google Earth, and Bing Maps, provided there are
geo-coded Places and Place Details (sites) in your database.
MapEvents-KML
query
7.2 Reports My Lists Multiple spouses Multi-spouses Lists persons with multiple spouses in descending number – may
flag a data problem
Multiple
Spouses query
7.2 Reports My Lists Nameless witnesses to shared facts TraceHeadlessWitnesses Report on the role, event and owner or principal of the shared
event for which a witness or sharee is no longer a person in the
database.
Shared
Events With Missing Witnesses
7.2 Reports My Lists To-Do Grid MyToDoList A Query for a To Do List in a Grid Format – using the REFN to
assign status for paragraphing and census. Versions for both SQLite
directly and MS Access via SQLODBC.
A
Query for a To Do List in a Grid Format
8

Tools

Hmm Tools within a Tool
8.1.1 Tools Merge Fast Duplicate Name Search DuplicateNameSearch Lists duplicate name pairs with a weighted score indicating degree
of match. On a large database, produces results in 4.5 minutes
similar to what RootsMagic 4’s Duplicate Search Merge tool does in
45 min.
Duplicate
Name Search – query
8.1.2 Tools Merge Mark unmerged not a problem MarkNotProblem Copies all unmerged pairs from the results of RM4’s Duplicate
Search Merge Tool to RM4’s ExclusionTable so that they will not
reappear in subsequent runs of Duplicate Search Merge.
Duplicate
Search Merge Database
G

Groups

Refresh – various Top page for a collection of queries for refreshing Named Groups Named Group
Refresh
G.1 Groups Ancestors AncestorsGroup Provides a manual refresh for a specific Named Group, i.e., the
ancestors of a specified person.
Ancestors
Named Group
G.2 Groups Census needed CensusNeededGroup | CensusNeededGroup2 Builds or refreshes a group of persons whose lifetime probably
spanned a user-defined Census Year and who had some event in the
user-defined jurisdiction but not a Census fact for that year.
Census
Needed – Named Group
G.3 Groups Mark/Unmark Lists Group Unmark List Refresh | Group Mark List Refresh Marks or Unmarks members of a group according to a list;
equivalent to memorising the checkboxes in RootsMagic Explorer for
re-use.
Named
Group – Mark or Unmark List refresh
zFn

functions

DateDecoder Decodes most of the possible formats found in RM4 Date fields of
the form Da+nnnnnnnn.x+nnnnnnnn.x
Date Decoder encode as SQLite function
zFn functions SortDateEncodeDecode for encoding single, pure dates and decoding corresponding
SortDates (no modifiers yet like bef, aft)
Dates –
SortDate Algorithm
encode as SQLite function

Discussions & comments from Wikispaces site


LessTX

Functions by Table modified

LessTX
11
January 2012 15:37:45
Warning: I don’t know what all of the current queries are, I
haven’t taken the time to look at the long list of stuff, it’s
currently too long and unstructure to make me believe that
it’s worth my time. In that, I’m probably like most folks who
come here, and am the kind of person this project is intended
to help.
Just be aware, my suggestions have NO relationship to whatever
work has already been done, just a relationship to my prior
program (TMG) and what I needed from a utility program, and
seem to still need from an RM utils program.
The utility program itself should have the standard
File/Edit/View/Tools/Help structure.
Users will come to the RMUtils program why? To either GET INFO
from their database or to CHANGE their database.
The pertinent areas are:
names, events, places, sources, repositories, media, others?
I absolutely see a structure similar to that of TMG being the
most intuitive for users.

ve3meo

ve3meo
21
January 2012 03:40:31

I have activated a Query Menu in the sidebar linking to a
new Query Menu page providing something of a structure that
hopefully helps newcomers navigate to a query of interest.

Genealogy Software Comparison #database

The following exchanges between Lee Irons and Tom Holden shed some light on the differences between RootsMagic and two other leading genealogy software programs (Legacy Family Tree 7.5 and Family Tree Maker 2012) and what can give rise to incompatabilities when data is transferred between them via GEDCOM.

 
Hi Tom,
There are software comparison reviews out there, but they are pretty much at the
thousand-foot altitude, basically useless to advanced users. I've been considering
putting together a comparison that gets down into the weeds on these three programs.

My email below just scratches the surface, as you know. The industry definitely
needs daylight shed on it so that people can see what they are really getting when
they purchase one of these programs. It might help provide some motivation to the
developers to get moving on cutting-edge enhancements and stop nibbling at the crumbs.
If you would like to post my email below as a precursor to a greater effort, then
please feel free. ;-)
Lee

-- Tom Holden wrote:
 
> Hi Lee,
>
> Great explanation of the differences among the three programs. I'm not aware
> of anybody having done this publicly. Would you be willing to contribute
> something like this to the SQLite Tools For RootsMagic wiki, or let me quote
> this on it? All in the interest of advancing our understanding of the
> characteristics of data imported into RM from other programs ;-)
>
> Tom
>
> ---Original Message---
> From: Lee Irons
> Sent: Sunday, December 18, 2011 11:53 PM
> To: 'Tom Holden'
> Subject: RE: Completed conversion of shared family facts
> ...
> Yes, you are correct regarding the differences in approach between the three
> programs. LFT 7.5 does 1-or-more-citations : 1-event/fact, but has a
> quasi-1-citation : many-events/facts functionality by allowing a source
> citation to be copied and pasted to other events and then appear to be one
> citation for the many events in reports and publications. LFT does not have
> "shared facts," but when a fact type is applied to a marriage, it becomes a
> marriage fact. FTM 2012 has a 1-or-more citations : 1-or-more-events/facts.
> In practice, the user can create 1 citation and link it to many events/facts
> with ease. It differentiates between individual facts, which can be shared
> by anyone, and marriage facts, which can only be applied to married couples.
> RM5, of course, takes the approach of having shared events. I'm sure the
> database structure is quite different for all of these.
>
> I would say that, of the three, LFT 7.5 has advanced merge, find,
> search-and-replace, and report/publication functionality. FTM 2012 has
> advanced sourcing, mapping, and heads-up-display functionality. RM 5 has
> advanced place management functionality (with county checker and place
> details), and has the only roles-for-shared-facts functionality of the
> three. All of these other functionality in all three has strengths and
> weaknesses.
>
> Regarding the way I cite sources and build evidence, my migration to RM 5
> taught me a lot of lessons and showed me some weaknesses in what I was
> doing. I have spent the last couple of weeks improving my methodology and
> now have something that would work with LFT or FTM without me needing to use
> the shared facts capability of RM 5. The Roots Magic developers seem to
> have their hands full with playing catch-up to the advanced capabilities of
> FTM and LFT, so I am going to keep my eye on RM for a while. Family Tree
> Maker 2012 is not perfect. It only recognizes current-day places (does not
> validate the existence of counties based upon date). Its fact sentence
> functionality is weak. It also does not chronologically order the facts on
> the person screen, nor does it allow the user to manually reorder them, so
> it looks messy. Also, its report and publications capability needs some
> work. However, LFT 7.5 has weak advanced sourcing , which makes me have to
> do a lot of clicking around, and copying and pasting to accomplish what I
> want. So I am focused on trying to make FTM 2012 work for me right now,
> because its source citation capability is that good. I have sent some
> enhancement requests off to Family Tree Maker developers for advanced fact
> management (needs better fact sentence creation capability and the ability
> to reorder facts), advanced place management (needs an Original Place Name
> field as opposed to the current Place field which only recognizes
> current-day place names for valid name checking and automatic mapping and a
> Date-Line Checker, similar to RM's County Checker), and advanced report
> customization. Legacy Family Tree would have to build in some Advanced
> Sourcing capability to bring me back. I've put in the enhancement requests
> to the LFT developers, but it looks unlikely that they are going to happen.
>
> Cheer!
>
> Lee
>
> ---Original Message---
> From: Tom Holden
> Sent: Friday, December 16, 2011 8:26 AM
> To: Lee Irons
> Subject: Re: Completed conversion of shared family facts
>
...
> I'm interested in your comment on FTM2012 as I was seriously thinking of
> giving it a try just about when RM5 came out and distracted me. Also, your
> description that it "merges the duplicate source citations into single
> source citations with multiple facts of multiple individuals linked to them"
>
> sounds different from what you were trying to do in RM5 which was to merge
> matching independent facts into shares of a single fact. Maybe the goal is
> the same (single citation for all) but the tools and solutions are
> necessarily different. In RM, every citation is uniquely linked to one
> person, or one family or one event - a 1:1 relationship. I wonder if, in FTM
> and LFT, multiple persons|families|events can link to one citation (many:1).
>
> Two very different database designs which could account for the difficulties
> in migrating between LFT and RM whereas it might be naturally easier between
> FTM and LFT. I did not even look at the LFT GEDCOM to see how it might
> differ.
>
> Tom
>
>
>
> ---Original Message---
> From: Lee Irons
> Sent: Friday, December 16, 2011 1:48 AM
> To: 'Tom Holden'
> Subject: RE: Completed conversion of shared family facts
>
> Tom,
>
...
> On the other hand, I have found that Family Tree Maker 2012 imports my
> Legacy file and merges the duplicate source citations into single source
> citations with multiple facts of multiple individuals linked to them. It
> does exactly what I want. It also has the ability to place a pin anywhere
> on a Bing map location to record the geocode for a place that it can't
> automatically find. The reporting capability isn't all that great, but I
> can move the data back and forth through a GEDCOM 5.5 file between Family
> Tree Maker and Legacy and use Legacy's reporting capability, which is top of
> the line.
>
> Long story short, I think I have found my solution using other software.
> Roots Magic had some nice things (like Place Details), but it appears that
> it would be too difficult to convert my data.
>
> Feel free to keep playing around with my data file as you like. I'll still
> keep an eye on the forum and get updates and upgrades to Roots Magic. Kind
> of a hobby.
>
> Cheers,
>
> Lee

MS Access, SQLite, and Don Quixote #msaccess #subqueries #rmnocase

I wanted to report some further investigations into my quest to be able to write the same query only once for use both directly in SQLite and again for MS Access, with hopefully not a whole lot editing required to make the same basic query work in either environment.

On the issue of what may be called the “nested JOIN” problem where Access wants to base queries on other queries, further testing and some sage advice from Tom suggests that this problem may be solved with nested SELECT’s rather than with nested JOIN’s, and the resultant SQL will work pretty much equally well in either environment. To wit, I am finding that I’m wanting to create queries that can be structured roughly as follows:

SELECT
        some_right_and_left_stuff
FROM
        (SELECT some_left_stuff FROM some_tables_on_the_left) AS L
LEFT JOIN
        (SELECT some_right_stuff FROM some_tables_on_the_right) AS R ON some_right_and_left_stuff;

Of course, both some_tables_on_the_left and some_tables_on_the_right may involve some additional JOINS, but the required parentheses and nesting seem so far to be totally compatible between Access and SQLite. But then, the RMNOCASE issue problem and the BLOB problem must be dealt with differently between Access and SQLite.

Here’s an example of a compatibility problem I didn’t expect. Suppose we replace “SELECT some_left_stuff FROM some_tables_on_the_left” from the third line of the pseudo-code with the following. It’s a real query that will run successfully on both environments. The query returns a list RM Record Numbers associated with a Named Group. In this example, it’s group #6, and I used the group number rather than the group name to avoid having to deal with text strings. Indeed, that’s why this query is so compatible – it references no text strings. I totally stole this query from Tom, by the way. I doubt I could have figured out how to do it on my own.

SELECT
        N.OwnerID AS Recno
 
FROM GroupTable AS G,
     PersonTable AS P INNER JOIN
     NameTable AS N ON P.PersonID=N.OwnerID
 
WHERE
       N.OwnerID >= G.StartID
            AND
       N.OwnerID <= G.EndID
            AND
       G.GroupID = 6

Next, we make the exact same query into one using nested SELECT’s. In this case, it’s totally silly to introduce an extra level of nesting just for this one query. But remember it’s ultimately our purpose to LEFT JOIN this query with another, and the best way to do the LEFT JOIN will surely be with nested SELECT’s.

SELECT
        L.RecNo AS RecNo
 
FROM
       (
         SELECT
                N.OwnerID AS Recno
 
         FROM GroupTable AS G,
              PersonTable AS P INNER JOIN
              NameTable AS N ON P.PersonID=N.OwnerID
 
        WHERE
 
          N.OwnerID >= G.StartID
               AND
          N.OwnerID <= G.EndID
               AND
          G.GroupID = 6
 
       ) AS L

Again, this query “just works” in both environments and it still produces a list of the all the RM Record Numbers associated with one particular Named Group. And again the reason the query works in both environments is that it is only dealing with numeric data. So let’s confuse things by adding one text field. We will start with the original query that was not nested.

SELECT
        N.OwnerID AS Recno,
        N.Surname AS Surname
 
FROM
      GroupTable AS G,
      PersonTable AS P INNER JOIN
      NameTable AS N ON P.PersonID=N.OwnerID
 
WHERE
 
      N.OwnerID >= G.StartID
           AND
      N.OwnerID <= G.EndID
           AND
      G.GroupID = 6

Perhaps a little surprisingly, this query still works in both environments even though I have added a text string to it, namely, NameTable.Surname. But I think it’s more or less by accident that the query works in both environments without any use of COLLATE NOCASE or CAST or StrConv. Which is to say, I’m not doing any manipulation or comparison of NameTable.Surname whatsoever.

Finally, we add a text string to the nested query.

SELECT
        L.RecNo AS RecNo,
        L.Surname AS Surname
 
FROM
      (
       SELECT
               N.OwnerID AS Recno,
               N.Surname AS Surname
 
       FROM
            GroupTable AS G,
            PersonTable AS P INNER JOIN
            NameTable AS N ON P.PersonID=N.OwnerID
 
       WHERE
              N.OwnerID >= G.StartID
                   AND
              N.OwnerID <= G.EndID
                   AND
              G.GroupID = 6
 
      ) AS L

This query still works fine in ACCESS, and indeed it’s more user friendly than before because it’s listing the person’s surname in addition to the person’s Record Number. But in SQLite the query gives one of those obnoxious “no such collation sequence: RMNOCASE” errors. I’m not doing any processing or manipulation or comparison of a text string, but there’s the error, anyway. I’m guessing that SQLite doing something that causes the collation sequence error because it’s converting the data from N.Surname in the innermost SELECT to L.Surname in the outermost SELECT. I can fix the query in SQLite by adding COLLATE NOCASE to Surname, but then the query will no longer work in Access. Apparently there is always going to be a lot of editing required to be able to have both an Access version and an SQLite version of the same query. And the query above is really simple.

Jerry

Discussions & comments from Wikispaces site


thejerrybryan

UPDATE Syntax, multiple tables

thejerrybryan
02 July 2011 15:12:34

I’m ready to play with an UPDATE transaction (in a test database, of course), but I need to update one table based on the contents of another table. The examples that I can find do not seem to work in SQLite.

The following works:

UPDATE SomeTable
SET SomeColumn=whatever
WHERE SomeOtherColumn=somethingelse

I need the WHERE clause to reference another table, and I can’t figure out how to do it. Conceptually, I need the following.

UPDATE SomeTable INNER JOIN SomeOtherTable ON some_condition
SET SomeTable.SomeColumn=whatever
WHERE SomeOtherTable.SomeOtherColumn=somethingelse

It certainly seems like this sort of thing ought to be very easy to do, but I can’t figure out the syntax.

Thanks,
Jerry


ve3meo

ve3meo
02 July 2011 20:03:16

Jerry, I wonder if Media Repair Queries might provide a solution. I banged my head against the same question and came up with that technique in the absence of anything better.

Sounds like you’re almost ready to roll out some neat stuff!

Tom

Inline comments


ve3meo

Comment: SQLiteSpy with a new extension provid…

ve3meo
16 December 2011 02:27:19

SQLiteSpy with a new extension providing a fake RMNOCASE collation should work without having to change the query to include COLLATE NOCASE.

Media Repair Queries #filenames #duplicates #media #links #rmnocase #delete #update

Importing and merging duplicates of persons, families, places and sources already in a database can give rise to unwanted proliferation of duplicate items in the Media Gallery and multiple links to the same media item from a person, family, event, place or source. RMGC_Properties – Query now reports the quantities of such duplicates. A problem database that I worked on had 80 duplicate file names and 160 duplicate links from persons, families, events, places or sources. One image had 42 links from the same Place. As the Media Gallery grows, it becomes increasingly difficult to notice duplicate image file names and much harder to identify and remove duplicate links.

The series of queries in this SQL file help to identify duplicate file names and duplicate links and demonstrates a repair for one case of how duplicate file names can arise and a repair for duplicate links, regardless of cause. The repair queries delete records and, unfortunately, require the use of a SQLite manager capable of faking a RMNOCASE collation sequence to update the associated indexes. The investigative queries can be run on any SQLite manager. CAUTION: untested with RM5 and may give unwanted results due to changes in the media tables.

MediaRepair.sql

Query

1. Lists duplicate media file names

MediaID MediaFile MediaPath
86 _East Dyberry Cemetery 1.JPG d:My DocumentsGenealogyGravestonesUSA – East Dyberry (Wayne Co)
93 _East Dyberry Cemetery 1.JPG E:My DocumentsGenealogyGravestonesUSA – East Dyberry (Wayne Co)
48 bailie-agnes,1885-jan-26-(b).jpg e:My DocumentsGenealogySurgeonerBirths
251 bailie-agnes,1885-jan-26-(b).jpg d:My DocumentsGenealogySurgeonerBirths

2. Creates a list of UPDATE commands to replace the MediaID in MediaLinkTable that points to the MultimediaTable record having the path to E drive with the MediaID of the same file on the D drive. Copy this list to another SQL edit page and run it. NB – this query was for the specific problem of this database: the same files were on two different drives having the same paths.

3. Query #2 produces a list of queries such as this:

command
UPDATE medialinktable SET MediaID=106 WHERE MediaID=107;
UPDATE medialinktable SET MediaID=108 WHERE MediaID=109;
UPDATE medialinktable SET MediaID=110 WHERE MediaID=111;

This list is copied into a SQL edit window of the SQLite manager and executed, sans the header “command”.

4. After UPDATing the MediaIDs in MediaLinkTable to the new MediaIDs, then run this query to delete the records with oldMediaIDs from MultimediaTable. REQUIRES SharpPlus SQLite Developer or other SQLite manager supporting a fake RMNOCASE collation.

5. Lists duplicate links in MediaLinkTable to media files in MultimediaTable

LinkID DUPES LinkedTo
138 1 _East Dyberry Cemetery 1.JPG
137 5 _East Dyberry Cemetery 7.JPG
76 1 bailie-agnes,1885-jan-26-(b).jpg
723 41 Ballyclare Town Hall.pcx

6. DELETEs duplicate links from MediaLinkTable. REQUIRES SharpPlus SQLite Developer, SQLiteSpy with extension, or other SQLite manager supporting a fake RMNOCASE collation.

County Check #county

RootsMagic 5 introduced a new feature that checks what you have entered in the Place of a fact/event against a database of counties stored in the file CountyCheckDB.dat. This file is partially human readable when opened in a text editor. What it reveals is that there are four Internet sites that it is set to call for maps and other information:

Tag URL Description
FSWIKI https://www.familysearch.org/learn/wiki/en/ Family Search Wiki
NAHCB https://publications.newberry.org/ahcbp/ Newberry Atlas of Historical County Boundaries (US)
WIKI http://en.wikipedia.org/wiki Wikipedia
http://maps.familysearch.org England Jurisdictions 1851

The first three appear to get parameters for a specific place that are appended to the URL and passed to the CountyCheck controls “Online Info” and “Online Map” to open these sites on a specific page. The last one is called without parameters for places in England.

RM5 Version Monitoring #database

The database documentation was done largely on RootsMagic version 5.0.0.3 and those released in the several days following. It’s unlikely that the database schema has changed as of the most-recent version. However, any changes may be detected by opening a database created by each version with a SQLite manager, then exporting either a query of the full sqlite_master table or the database schema (just the SQL field of that table wrapped in a transaction) and comparing the exports from each version using a text editor that has a compare function (e.g. Notepad++).

The page RM5 Database System Catalog displays the full sqlite_master table from 5.0.0.6.

For future comparisons, below is the schema from 5.0.0.6:

BEGIN TRANSACTION;
CREATE TABLE AddressLinkTable (LinkID INTEGER PRIMARY KEY, OwnerType INTEGER, AddressID INTEGER, OwnerID INTEGER, AddressNum INTEGER, Details TEXT );
CREATE TABLE AddressTable (AddressID INTEGER PRIMARY KEY, AddressType INTEGER, Name TEXT COLLATE RMNOCASE, Street1 TEXT, Street2 TEXT, City TEXT, State TEXT, Zip TEXT, Country TEXT, Phone1 TEXT, Phone2 TEXT, Fax TEXT, Email TEXT, URL TEXT, Latitude INTEGER, Longitude INTEGER, Note BLOB );
CREATE TABLE ChildTable (RecID INTEGER PRIMARY KEY, ChildID INTEGER, FamilyID INTEGER, RelFather INTEGER, RelMother INTEGER, ChildOrder INTEGER, IsPrivate INTEGER, ProofFather INTEGER, ProofMother INTEGER, Note BLOB );
CREATE TABLE CitationTable (CitationID INTEGER PRIMARY KEY, OwnerType INTEGER, SourceID INTEGER, OwnerID INTEGER, Quality TEXT, IsPrivate INTEGER, Comments BLOB, ActualText BLOB, RefNumber TEXT, Flags INTEGER, FIELDS BLOB );
CREATE TABLE ConfigTable (RecID INTEGER PRIMARY KEY, RecType INTEGER, Title TEXT, DataRec BLOB );
CREATE TABLE EventTable (EventID INTEGER PRIMARY KEY, EventType INTEGER, OwnerType INTEGER, OwnerID INTEGER, FamilyID INTEGER, PlaceID INTEGER, SiteID INTEGER, DATE TEXT, SortDate INTEGER, IsPrimary INTEGER, IsPrivate INTEGER, Proof INTEGER, STATUS INTEGER, EditDate FLOAT, Sentence BLOB, Details BLOB, Note BLOB );
CREATE TABLE ExclusionTable (RecID INTEGER PRIMARY KEY, ExclusionType INTEGER, ID1 INTEGER, ID2 INTEGER );
CREATE TABLE FactTypeTable (FactTypeID INTEGER PRIMARY KEY, OwnerType INTEGER, Name TEXT COLLATE RMNOCASE, Abbrev TEXT, GedcomTag TEXT, UseValue INTEGER, UseDate INTEGER, UsePlace INTEGER, Sentence BLOB, Flags INTEGER );
CREATE TABLE FamilyTable (FamilyID INTEGER PRIMARY KEY, FatherID INTEGER, MotherID INTEGER, ChildID INTEGER, HusbOrder INTEGER, WifeOrder INTEGER, IsPrivate INTEGER, Proof INTEGER, SpouseLabel INTEGER, FatherLabel INTEGER, MotherLabel INTEGER, Note BLOB );
CREATE TABLE GroupTable (RecID INTEGER PRIMARY KEY, GroupID INTEGER, StartID INTEGER, EndID INTEGER );
CREATE TABLE LabelTable (LabelID INTEGER PRIMARY KEY, LabelType INTEGER, LabelValue INTEGER, LabelName TEXT COLLATE RMNOCASE, Description TEXT );
CREATE TABLE LinkTable (LinkID INTEGER PRIMARY KEY, extSystem INTEGER, LinkType INTEGER, rmID INTEGER, extID TEXT, Modified INTEGER, extVersion TEXT, extDate FLOAT, STATUS INTEGER, Note BLOB );
CREATE TABLE MediaLinkTable (LinkID INTEGER PRIMARY KEY, MediaID INTEGER, OwnerType INTEGER, OwnerID INTEGER, IsPrimary INTEGER, Include1 INTEGER, Include2 INTEGER, Include3 INTEGER, Include4 INTEGER, SortOrder INTEGER, RectLeft INTEGER, RectTop INTEGER, RectRight INTEGER, RectBottom INTEGER, Note TEXT, Caption TEXT COLLATE RMNOCASE, RefNumber TEXT COLLATE RMNOCASE, DATE TEXT, SortDate INTEGER, Description BLOB );
CREATE TABLE MultimediaTable (MediaID INTEGER PRIMARY KEY, MediaType INTEGER, MediaPath TEXT, MediaFile TEXT COLLATE RMNOCASE, URL TEXT, Thumbnail BLOB , Caption TEXT COLLATE RMNOCASE, RefNumber TEXT COLLATE RMNOCASE, DATE TEXT, SortDate INTEGER, Description BLOB);
CREATE TABLE NameTable (NameID INTEGER PRIMARY KEY, OwnerID INTEGER, Surname TEXT COLLATE RMNOCASE, Given TEXT COLLATE RMNOCASE, Prefix TEXT COLLATE RMNOCASE, Suffix TEXT COLLATE RMNOCASE, Nickname TEXT COLLATE RMNOCASE, NameType INTEGER, DATE TEXT, SortDate INTEGER, IsPrimary INTEGER, IsPrivate INTEGER, Proof INTEGER, EditDate FLOAT, Sentence BLOB, Note BLOB, BirthYear INTEGER, DeathYear INTEGER );
CREATE TABLE PersonTable (PersonID INTEGER PRIMARY KEY, UniqueID TEXT, Sex INTEGER, EditDate FLOAT, ParentID INTEGER, SpouseID INTEGER, Color INTEGER, Relate1 INTEGER, Relate2 INTEGER, Flags INTEGER, Living INTEGER, IsPrivate INTEGER, Proof INTEGER, Bookmark INTEGER, Note BLOB );
CREATE TABLE PlaceTable (PlaceID INTEGER PRIMARY KEY, PlaceType INTEGER, Name TEXT COLLATE RMNOCASE, Abbrev TEXT, Normalized TEXT, Latitude INTEGER, Longitude INTEGER, LatLongExact INTEGER, MasterID INTEGER, Note BLOB );
CREATE TABLE ResearchItemTable (ItemID INTEGER PRIMARY KEY, LogID INTEGER, DATE TEXT, SortDate INTEGER, RefNumber TEXT, Repository TEXT, Goal TEXT, SOURCE TEXT, RESULT TEXT );
CREATE TABLE RoleTable (RoleID INTEGER PRIMARY KEY, RoleName TEXT COLLATE RMNOCASE, EventType INTEGER, RoleType INTEGER, Sentence TEXT );
CREATE TABLE SourceTable (SourceID INTEGER PRIMARY KEY, Name TEXT COLLATE RMNOCASE, RefNumber TEXT, ActualText TEXT, Comments TEXT, IsPrivate INTEGER, TemplateID INTEGER, FIELDS BLOB );
CREATE TABLE SourceTemplateTable (TemplateID INTEGER PRIMARY KEY, Name TEXT COLLATE RMNOCASE, Description TEXT, Favorite INTEGER, Category TEXT, Footnote TEXT, ShortFootnote TEXT, Bibliography TEXT, FieldDefs BLOB );
CREATE TABLE WitnessTable (WitnessID INTEGER PRIMARY KEY, EventID INTEGER, PersonID INTEGER, WitnessOrder INTEGER, ROLE INTEGER, Sentence TEXT, Note BLOB, Given TEXT COLLATE RMNOCASE, Surname TEXT COLLATE RMNOCASE, Prefix TEXT COLLATE RMNOCASE, Suffix TEXT COLLATE RMNOCASE );
CREATE INDEX idxAddressName ON AddressTable (Name);
CREATE INDEX idxChildFamilyID ON ChildTable (FamilyID);
CREATE INDEX idxChildID ON ChildTable (ChildID);
CREATE INDEX idxChildOrder ON ChildTable (ChildOrder);
CREATE INDEX idxCitationOwnerID ON CitationTable (OwnerID);
CREATE INDEX idxCitationSourceID ON CitationTable (SourceID);
CREATE UNIQUE INDEX idxExclusionIndex ON ExclusionTable (ExclusionType, ID1, ID2);
CREATE INDEX idxFactTypeAbbrev ON FactTypeTable (Abbrev);
CREATE INDEX idxFactTypeGedcomTag ON FactTypeTable (GedcomTag);
CREATE INDEX idxFactTypeName ON FactTypeTable (Name);
CREATE INDEX idxFamilyFatherID ON FamilyTable (FatherID);
CREATE INDEX idxFamilyMotherID ON FamilyTable (MotherID);
CREATE INDEX idxGiven ON NameTable (Given);
CREATE INDEX idxLabelType ON LabelTable (LabelType);
CREATE INDEX idxLinkExtId ON LinkTable (extID);
CREATE INDEX idxLinkRmId ON LinkTable (rmID);
CREATE INDEX idxMediaCaption ON MediaLinkTable (Caption);
CREATE INDEX idxMediaFile ON MultimediaTable (MediaFile);
CREATE INDEX idxMediaOwnerID ON MediaLinkTable (OwnerID);
CREATE INDEX idxMediaURL ON MultimediaTable (URL);
CREATE INDEX idxNameOwnerID ON NameTable (OwnerID);
CREATE INDEX idxNamePrimary ON NameTable (IsPrimary);
CREATE INDEX idxOwnerDate ON EventTable (OwnerID,SortDate);
CREATE INDEX idxOwnerEvent ON EventTable (OwnerID,EventType);
CREATE INDEX idxPlaceAbbrev ON PlaceTable (Abbrev);
CREATE INDEX idxPlaceName ON PlaceTable (Name);
CREATE INDEX idxRecType ON ConfigTable (RecType);
CREATE INDEX idxResearchItemLogID ON ResearchItemTable (LogID);
CREATE INDEX idxResearchName ON ResearchTable (Name);
CREATE INDEX idxResearchOwnerID ON ResearchTable (OwnerID);
CREATE INDEX idxRoleEventType ON RoleTable (EventType);
CREATE INDEX idxSourceName ON SourceTable (Name);
CREATE INDEX idxSourceTemplateName ON SourceTemplateTable (Name);
CREATE INDEX idxSurname ON NameTable (Surname);
CREATE INDEX idxSurnameGiven ON NameTable (Surname, Given, BirthYear, DeathYear);
CREATE INDEX idxWitnessEventID ON WitnessTable (EventID);
CREATE INDEX idxWitnessPersonID ON WitnessTable (PersonID);
COMMIT TRANSACTION;

RM5 Table Summaries #datadefinitions

The following non-system tables currently reside in the RM5 database:

Name Description
AddressLinkTable Translates OwnerID from various tables to the key AddressID in AddressTable.
AddressTable Stores Addresses for Persons in the tree, Repositories, and other entities that need not be in the tree. Note that the Name in this table is not the same as the names in the NameTable.
ChildTable Stores relationship to family(ies) for each child. A child may have two or more families – e.g., birth and adoptive. Links to PersonTable for child and to FamilyTable for parents.
CitationTable Stores Citation details with links to PersonTable, FamilyTable, and EventTable and to the SourceTable for the sources cited. One record per citation.
ConfigTable Stores File settings, Report settings, Fonts, etc to preserve between sessions.
EventTable Stores details for each Fact/Event with links to Persons, Families having the event and to the FactTypeTable for the Fact properties.
ExclusionTable Stores Problem List items indicated by user as Not a problem.
FactTypeTable Definition of the standard and user-defined Facts related to by the EventTable.
FamilyTable Stores Family pairings, spousal order, and notes.
GroupTable Stores data for Named Groups: ranges of PersonID’s from PersonTable that were marked for the group.
LabelTable Stores labels for Named Groups and probably other labels, too.
LinkTable Probably has to do with New Family Search support and future support for remote Media.
MediaLinkTable Stores relationship between records in MultiMediaTable and Person, Event, Place Tables along with settings for use in reports or scrapbooks, captions, notes (unused?), descriptions.
MultimediaTable Stores path and name to Media files, a type of media code, URL (unused as of 5.0.0.6), and binary thumbnail for image files.
NameTable Stores name parts for persons in tree, including Alternate Names as separate records (unlimited), primary and privacy settings, birth year and death year.
PersonTable Stores basic data for persons in tree: globally Unique ID as well as internal PersonID, FamilyID of parent family and PersonID of spouse, calculated relationship to other person in tree, privacy and living flags, and general note.
PlaceTable Stores system pre-defined and user-defined Places and Place Details (or sites) with Name, Abbreviation, Normalized Name, geographical coordinates, and notes. Linked from eventtable.
ResearchItemTable Stores
ResearchTable Stores contents of To-Do list with link to PersonTable or FamilyTable, depending on where task was created.
RoleTable Stores system pre-defined and user-defined Roles with sentence templates for most FactTypes, linked from WitnessTable.
SourceTable Stores Citation Source details for each unique source, linked from CitationTable (many to 1 allowed); linked to AddressTable for Source Repository and to SourceTemplateTable for support of Citation data entry and reports.
SourceTemplateTable Stores system pre-defined and user-defined sentence and field templates for different kinds of citation sources, following published guidelines. Linked from SourceTable for support of Citation data entry and reports.
WitnessTable Stores data for individual and family Event sharing among persons in tree and outside the tree, with links to RoleTable (Witness, Doctor, user-defined), EventTable, and to PersonTable (if in tree). Stores note for shared event plus name of person if not in tree. If person is not in tree, nothing of this record appears in reports.

RM5 Database System Catalog #datadefinitions

A singular system table, sqlite_master, resides in a SQLite database. The table in the RootsMagic 5 database essentially defines the RootsMagic 5 database tables, indices, and fields, as below.

Differences in structure with RootsMagic 4 include the addition of a new table, ResearchItemTable (and its index), to incorporate the newly-incorporated Research Log feature. In addition, MultimediaTable now includes five additional fields to account for the revised treatment of media throughout the program.

type name tbl_name rootpage sql
table ConfigTable ConfigTable 2 CREATE TABLE ConfigTable (RecID INTEGER PRIMARY KEY, RecType INTEGER, Title TEXT, DataRec BLOB )
index idxRecType ConfigTable 3 CREATE INDEX idxRecType ON ConfigTable (RecType)
table PersonTable PersonTable 4 CREATE TABLE PersonTable (PersonID INTEGER PRIMARY KEY, UniqueID TEXT, Sex INTEGER, EditDate FLOAT, ParentID INTEGER, SpouseID INTEGER, Color INTEGER, Relate1 INTEGER, Relate2 INTEGER, Flags INTEGER, Living INTEGER, IsPrivate INTEGER, Proof INTEGER, Bookmark INTEGER, Note BLOB )
table FamilyTable FamilyTable 5 CREATE TABLE FamilyTable (FamilyID INTEGER PRIMARY KEY, FatherID INTEGER, MotherID INTEGER, ChildID INTEGER, HusbOrder INTEGER, WifeOrder INTEGER, IsPrivate INTEGER, Proof INTEGER, SpouseLabel INTEGER, FatherLabel INTEGER, MotherLabel INTEGER, Note BLOB )
index idxFamilyFatherID FamilyTable 6 CREATE INDEX idxFamilyFatherID ON FamilyTable (FatherID)
index idxFamilyMotherID FamilyTable 8 CREATE INDEX idxFamilyMotherID ON FamilyTable (MotherID)
table ChildTable ChildTable 10 CREATE TABLE ChildTable (RecID INTEGER PRIMARY KEY, ChildID INTEGER, FamilyID INTEGER, RelFather INTEGER, RelMother INTEGER, ChildOrder INTEGER, IsPrivate INTEGER, ProofFather INTEGER, ProofMother INTEGER, Note BLOB )
index idxChildID ChildTable 11 CREATE INDEX idxChildID ON ChildTable (ChildID)
index idxChildFamilyID ChildTable 12 CREATE INDEX idxChildFamilyID ON ChildTable (FamilyID)
index idxChildOrder ChildTable 13 CREATE INDEX idxChildOrder ON ChildTable (ChildOrder)
table EventTable EventTable 14 CREATE TABLE EventTable (EventID INTEGER PRIMARY KEY, EventType INTEGER, OwnerType INTEGER, OwnerID INTEGER, FamilyID INTEGER, PlaceID INTEGER, SiteID INTEGER, Date TEXT, SortDate INTEGER, IsPrimary INTEGER, IsPrivate INTEGER, Proof INTEGER, Status INTEGER, EditDate FLOAT, Sentence BLOB, Details BLOB, Note BLOB )
index idxOwnerEvent EventTable 15 CREATE INDEX idxOwnerEvent ON EventTable (OwnerID,EventType)
index idxOwnerDate EventTable 17 CREATE INDEX idxOwnerDate ON EventTable (OwnerID,SortDate)
table AddressTable AddressTable 18 CREATE TABLE AddressTable (AddressID INTEGER PRIMARY KEY, AddressType INTEGER, Name TEXT COLLATE RMNOCASE, Street1 TEXT, Street2 TEXT, City TEXT, State TEXT, Zip TEXT, Country TEXT, Phone1 TEXT, Phone2 TEXT, Fax TEXT, Email TEXT, URL TEXT, Latitude INTEGER, Longitude INTEGER, Note BLOB )
index idxAddressName AddressTable 19 CREATE INDEX idxAddressName ON AddressTable (Name)
table FactTypeTable FactTypeTable 20 CREATE TABLE FactTypeTable (FactTypeID INTEGER PRIMARY KEY, OwnerType INTEGER, Name TEXT COLLATE RMNOCASE, Abbrev TEXT, GedcomTag TEXT, UseValue INTEGER, UseDate INTEGER, UsePlace INTEGER, Sentence BLOB, Flags INTEGER )
index idxFactTypeName FactTypeTable 21 CREATE INDEX idxFactTypeName ON FactTypeTable (Name)
index idxFactTypeAbbrev FactTypeTable 22 CREATE INDEX idxFactTypeAbbrev ON FactTypeTable (Abbrev)
index idxFactTypeGedcomTag FactTypeTable 24 CREATE INDEX idxFactTypeGedcomTag ON FactTypeTable (GedcomTag)
table MultimediaTable MultimediaTable 25 CREATE TABLE MultimediaTable (MediaID INTEGER PRIMARY KEY, MediaType INTEGER, MediaPath TEXT, MediaFile TEXT COLLATE RMNOCASE, URL TEXT, Thumbnail BLOB , Caption TEXT COLLATE RMNOCASE, RefNumber TEXT COLLATE RMNOCASE, Date TEXT, SortDate INTEGER, Description BLOB)
index idxMediaFile MultimediaTable 26 CREATE INDEX idxMediaFile ON MultimediaTable (MediaFile)
index idxMediaURL MultimediaTable 27 CREATE INDEX idxMediaURL ON MultimediaTable (URL)
table MediaLinkTable MediaLinkTable 28 CREATE TABLE MediaLinkTable (LinkID INTEGER PRIMARY KEY, MediaID INTEGER, OwnerType INTEGER, OwnerID INTEGER, IsPrimary INTEGER, Include1 INTEGER, Include2 INTEGER, Include3 INTEGER, Include4 INTEGER, SortOrder INTEGER, RectLeft INTEGER, RectTop INTEGER, RectRight INTEGER, RectBottom INTEGER, Note TEXT, Caption TEXT COLLATE RMNOCASE, RefNumber TEXT COLLATE RMNOCASE, Date TEXT, SortDate INTEGER, Description BLOB )
index idxMediaOwnerID MediaLinkTable 30 CREATE INDEX idxMediaOwnerID ON MediaLinkTable (OwnerID)
index idxMediaCaption MediaLinkTable 31 CREATE INDEX idxMediaCaption ON MediaLinkTable (Caption)
table NameTable NameTable 32 CREATE TABLE NameTable (NameID INTEGER PRIMARY KEY, OwnerID INTEGER, Surname TEXT COLLATE RMNOCASE, Given TEXT COLLATE RMNOCASE, Prefix TEXT COLLATE RMNOCASE, Suffix TEXT COLLATE RMNOCASE, Nickname TEXT COLLATE RMNOCASE, NameType INTEGER, Date TEXT, SortDate INTEGER, IsPrimary INTEGER, IsPrivate INTEGER, Proof INTEGER, EditDate FLOAT, Sentence BLOB, Note BLOB, BirthYear INTEGER, DeathYear INTEGER )
index idxNameOwnerID NameTable 34 CREATE INDEX idxNameOwnerID ON NameTable (OwnerID)
index idxSurname NameTable 35 CREATE INDEX idxSurname ON NameTable (Surname)
index idxGiven NameTable 36 CREATE INDEX idxGiven ON NameTable (Given)
index idxSurnameGiven NameTable 37 CREATE INDEX idxSurnameGiven ON NameTable (Surname, Given, BirthYear, DeathYear)
index idxNamePrimary NameTable 38 CREATE INDEX idxNamePrimary ON NameTable (IsPrimary)
table PlaceTable PlaceTable 39 CREATE TABLE PlaceTable (PlaceID INTEGER PRIMARY KEY, PlaceType INTEGER, Name TEXT COLLATE RMNOCASE, Abbrev TEXT, Normalized TEXT, Latitude INTEGER, Longitude INTEGER, LatLongExact INTEGER, MasterID INTEGER, Note BLOB )
index idxPlaceName PlaceTable 41 CREATE INDEX idxPlaceName ON PlaceTable (Name)
index idxPlaceAbbrev PlaceTable 42 CREATE INDEX idxPlaceAbbrev ON PlaceTable (Abbrev)
table ResearchTable ResearchTable 43 CREATE TABLE ResearchTable (TaskID INTEGER PRIMARY KEY, TaskType INTEGER, OwnerID INTEGER, OwnerType INTEGER, RefNumber TEXT, Name TEXT COLLATE RMNOCASE, Status INTEGER, Priority INTEGER, Date1 TEXT, Date2 TEXT, Date3 TEXT, SortDate1 INTEGER, SortDate2 INTEGER, SortDate3 INTEGER, Filename TEXT, Details BLOB )
index idxResearchOwnerID ResearchTable 44 CREATE INDEX idxResearchOwnerID ON ResearchTable (OwnerID)
index idxResearchName ResearchTable 45 CREATE INDEX idxResearchName ON ResearchTable (Name)
table SourceTable SourceTable 46 CREATE TABLE SourceTable (SourceID INTEGER PRIMARY KEY, Name TEXT COLLATE RMNOCASE, RefNumber TEXT, ActualText TEXT, Comments TEXT, IsPrivate INTEGER, TemplateID INTEGER, Fields BLOB )
index idxSourceName SourceTable 48 CREATE INDEX idxSourceName ON SourceTable (Name)
table CitationTable CitationTable 49 CREATE TABLE CitationTable (CitationID INTEGER PRIMARY KEY, OwnerType INTEGER, SourceID INTEGER, OwnerID INTEGER, Quality TEXT, IsPrivate INTEGER, Comments BLOB, ActualText BLOB, RefNumber TEXT, Flags INTEGER, Fields BLOB )
index idxCitationSourceID CitationTable 50 CREATE INDEX idxCitationSourceID ON CitationTable (SourceID)
index idxCitationOwnerID CitationTable 51 CREATE INDEX idxCitationOwnerID ON CitationTable (OwnerID)
table AddressLinkTable AddressLinkTable 52 CREATE TABLE AddressLinkTable (LinkID INTEGER PRIMARY KEY, OwnerType INTEGER, AddressID INTEGER, OwnerID INTEGER, AddressNum INTEGER, Details TEXT )
table WitnessTable WitnessTable 53 CREATE TABLE WitnessTable (WitnessID INTEGER PRIMARY KEY, EventID INTEGER, PersonID INTEGER, WitnessOrder INTEGER, Role INTEGER, Sentence TEXT, Note BLOB, Given TEXT COLLATE RMNOCASE, Surname TEXT COLLATE RMNOCASE, Prefix TEXT COLLATE RMNOCASE, Suffix TEXT COLLATE RMNOCASE )
index idxWitnessEventID WitnessTable 55 CREATE INDEX idxWitnessEventID ON WitnessTable (EventID)
index idxWitnessPersonID WitnessTable 56 CREATE INDEX idxWitnessPersonID ON WitnessTable (PersonID)
table LinkTable LinkTable 57 CREATE TABLE LinkTable (LinkID INTEGER PRIMARY KEY, extSystem INTEGER, LinkType INTEGER, rmID INTEGER, extID TEXT, Modified INTEGER, extVersion TEXT, extDate FLOAT, Status INTEGER, Note BLOB )
index idxLinkRmId LinkTable 58 CREATE INDEX idxLinkRmId ON LinkTable (rmID)
index idxLinkExtId LinkTable 59 CREATE INDEX idxLinkExtId ON LinkTable (extID)
table RoleTable RoleTable 60 CREATE TABLE RoleTable (RoleID INTEGER PRIMARY KEY, RoleName TEXT COLLATE RMNOCASE, EventType INTEGER, RoleType INTEGER, Sentence TEXT )
index idxRoleEventType RoleTable 62 CREATE INDEX idxRoleEventType ON RoleTable (EventType)
table GroupTable GroupTable 63 CREATE TABLE GroupTable (RecID INTEGER PRIMARY KEY, GroupID INTEGER, StartID INTEGER, EndID INTEGER )
table ExclusionTable ExclusionTable 64 CREATE TABLE ExclusionTable (RecID INTEGER PRIMARY KEY, ExclusionType INTEGER, ID1 INTEGER, ID2 INTEGER )
index idxExclusionIndex ExclusionTable 65 CREATE UNIQUE INDEX idxExclusionIndex ON ExclusionTable (ExclusionType, ID1, ID2)
table SourceTemplateTable SourceTemplateTable 66 CREATE TABLE SourceTemplateTable (TemplateID INTEGER PRIMARY KEY, Name TEXT COLLATE RMNOCASE, Description TEXT, Favorite INTEGER, Category TEXT, Footnote TEXT, ShortFootnote TEXT, Bibliography TEXT, FieldDefs BLOB )
index idxSourceTemplateName SourceTemplateTable 67 CREATE INDEX idxSourceTemplateName ON SourceTemplateTable (Name)
table LabelTable LabelTable 69 CREATE TABLE LabelTable (LabelID INTEGER PRIMARY KEY, LabelType INTEGER, LabelValue INTEGER, LabelName TEXT COLLATE RMNOCASE, Description TEXT )
index idxLabelType LabelTable 70 CREATE INDEX idxLabelType ON LabelTable (LabelType)
table ResearchItemTable ResearchItemTable 288 CREATE TABLE ResearchItemTable (ItemID INTEGER PRIMARY KEY, LogID INTEGER, Date TEXT, SortDate INTEGER, RefNumber TEXT, Repository TEXT, Goal TEXT, Source TEXT, Result TEXT )
index idxResearchItemLogID ResearchItemTable 304 CREATE INDEX idxResearchItemLogID ON ResearchItemTable (LogID)