DunsanakQL - Family Tree Query Language

· rtnF ·

7 min read Original article ↗

So, today, a certain relative of mine gave me an invitation letter for the wedding of another certain relative of mine.

I’m quite impressed with that invitation letter, since it actually lists several of my close relatives whom I know well. The names of my close relatives are printed inside the invitation letter. And since this invitation is copied en masse for other guests, I guess we’re relatively well-known here.

Then I thought to myself... this list of names inside the invitation is quite a treasure in itself. It contains critical information that could help complete my family tree, a quest that I’ve been pursuing for years and still haven’t quite finished.

From this list, I could get the names of many of my relatives, both close and distant. But I think I should also encode additional information about the relationships between those relatives (whether they’re connected as parent and child or as spouses), and add it to the giant, unified family tree centered on myself.

Now, I wish we had something like SQL, but designed to store and query connections in a family tree.

In SQL, you can add data piece by piece, step by step, into one giant database, which may contain several tables, each of which may contain several columns. All of those tables and columns may be related to one another.

In this family-tree query language, maybe we could do the same.

We would add data piece by piece, one nuclear family at a time.

We define one nuclear family as the singular, atomic unit of the family tree. The entire family tree consists of many nuclear families.

One nuclear family consists of a biological father, a biological mother, and their ordered list of biological children.

We define it using this syntax:

[Dad - Mom] : [Child1, Child2, Child3]

So, in this case, the first nuclear family that we want to add to the family-tree database would probably be the one that contains ourselves as a child.

Something like this (this is just an example):

[Dad - Mom] : [Me, Younger Sibling]

When we enter this command into the system, the system assigns an ID to each person in that family. These IDs are then used to connect one nuclear family to another.

For example, in this case, Dad is #1, Mom is #2, I’m #3, and my younger sibling is #4.

Next, we expand the family tree by adding more nuclear families. This time, I want to add my mom’s family.

[MyGrandfather - MyGrandmother] : [MyAunt, #2, MyAunt, MyUncle, MyUncle]

Here, I use #2 as a pointer to my mom.

Then, execute the command.

The system assigns IDs to the newly added family members:

#5  : MyGrandfather
#6  : MyGrandmother
#7  : MyAunt
#8  : MyAunt
#9  : MyUncle
#10 : MyUncle

Then, keep going and enter more data.

This is my own family tree, but all of the real names have been REDACTED. There are still a lot of people marked as “???”, since I can confirm that they exist, but I still haven’t learned their names. Maybe I should visit them more often.

After all the data has been entered into the system, we can query it to list all the relatives of a given person ID, sorted from closest to most distant, and grouped into several categories: Mom’s branch, Dad’s branch, spouse’s branch, and the rest (usually in-laws).

To query it, use this command:

c <personID>

For example:

c 1

This would gather and sort all of my relatives.

Here’s the source code, and here’s the live demo.

All data is stored locally in your own browser and is never sent to any server.

Oh, and a few additional features: right-click on someone’s name to rename them, and right-click on a family entry if you want to delete the entire family and all of its members.

And if you really want to reset everything, open Developer Tools → Application → Local Storage, find the familysql_db key, and delete it.

Epilogue

In my clan, there’s a tradition of maintaining a very large family tree, called a ranji. It’s a super serious matter because some claims regarding ancestral sacred land and hereditary titles are directly tied to this family tree. These clan-based family trees are often notarized by local chieftains and witnessed by several customary leaders to prevent family disputes in the future.

A prologue letter of the Minangkabau ranji, dated 18 June 1933 in Kp. Panas, Duku Banyak, Pariaman, West Sumatra.

In Minangkabau culture, ranji refers to a genealogical chart or lineage record that shows family descent, especially within a clan. Minangkabau society is matrilineal, meaning lineage is traced through the mother’s line, so a ranji is used to document how individuals are connected through that maternal ancestry.

Traditionally, a ranji lists generations of a clan, often starting from an ancestral woman or an early founding figure of the lineage in a particular nagari. It helps determine kinship relations, marriage eligibility, inheritance rights, and social roles within the adat system. Because marriage within the same matrilineal clan is prohibited in Minangkabau tradition, a ranji can function as a practical reference to avoid such unions.

Historically, these records could be written manuscripts kept by clan leaders or elders.

I have some of those ancient documents right here in my room. They’re written in the old Jawi script, so I ended up making yet another app to transcribe and translate them.

While studying those documents, I realized that the traditional two-dimensional “tree” representation of a family tree — in the computer science data structure sense — is still incomplete. Only the matrilineal line is represented, so a lot of important information is missing. From that point on, I started wishing for a representation that could actually cover all those missing cases.

At first, I tried using a graph-based representation, but because it really requires more than two dimensions to represent everything properly, it became messy very quickly.

That’s when I thought that maybe it’s simply impossible to represent everything correctly on a single two-dimensional screen. So instead, I resorted to listing each person’s relatives, sorted from closest to farthest, and grouped into “dad’s branch,” “mom’s branch,” and “spouse’s branch.”

To understand the bigger picture, you have to query it one person at a time, tracing the family tree through its depth and breadth.

Because maintaining all of this is so complicated, I decided to build this app.

Even now, there are still several major branches of the family tree that haven’t been connected to my main tree.

During our yearly family gathering, I repeatedly ask my parents, “What’s the actual relationship between our family and their family?” They patiently explain it every single time, and somehow I still can’t keep it straight because the relationship is simply too distant and too complicated. Usually, whenever I ask, I don’t even have anything to take notes with.

At this point, I’m almost too shy to ask again.

This afternoon, some of my relatives even laughed at me because I was studying a wedding invitation far too seriously.

“What are you doing? Are you planning to rewrite every name on that invitation and store it in your diary? That’s hilarious.”

What they don’t realize is that my own family tree has grown so large because my father actively keeps in touch with branches of the family that are incredibly distant from our own. That’s probably because he’s involved in maintaining the ranji. Since I’m expected to inherit that responsibility one day, I feel that I should improve the tools I use to manage this ever-growing collection of family data.

That’s why I take our yearly family gathering so seriously.

To me, it’s essentially an annual census. Especially for the newborns. Every year, there are new names waiting to be added to the family tree.

Discussion about this post

Ready for more?