what's up what's up what's up welcome
back today we're working on my to-do
file system uh so the idea is I have
things that I want to accomplish
basically what we've written in the top
right here right like we have items that
are approximately this we have like a
project that we're working on as well as
like chunks of work that are
approximately one Stream Long right and
as we kind of work as like I work
towards a stream on a topic I might want
to like stub out
uh what's important like what like the
list of tasks are for that stream and
sometimes when I'm doing this I like
find like oh this doesn't really fit
here it makes more sense to do this in
in this other chunk of work after cool
so far nothing crazy um the way I
represent this right now is just like a
bunch of files on my disc and basically
like before each stream I have like a
new file with the date and I say like
this is what's going to happen this day
and I can plan like a couple days ahead
but it's kind of hard to like prep out
what I'm going to do for like a week or
like for a project and sometimes I like
start like finding myself forgetting
what I want to get done in a project etc
etc so uh I want some sort of way to
like track these tasks a little bit
better um the like obvious first thought
there for me is like oh Trello people
use Trello for stuff like this right you
have like grids of like cards and cards
have like stuff to do in them but I
don't really like uh I don't really want
like one I don't want my data to be on
the internet two I want like uh I I
don't want to have to like open up a web
browser and go to a website to do all
this like feels like the actual editing
part of the task feels good the way it
is and it like feels like a bunch of
extra complexity that I don't need so
out the window there um then I think
about like well what's like the dumb
dumb caveman way that I would fix this
problem and it's like well I would just
for each task I would like put some Sim
links between them right for this task I
link to this one this one I link back to
this one um but then like managing those
Sim links starts to become a little
difficult because they're like two-way
relationships and so if I delete the Sim
link from one folder um I want to be
able to like navigate back and forth
between them so I want like some sort of
like two-way State handling but like the
idea of just like folders that are Sim
link together feels pretty close to what
I want um and so kind of I kind of
arrived at the idea of well what if we
just manage those Sim links in an
application for us and so like
implementing like a shitty little file
system to basically manage Sim links
between items in a database for us um
seems like it should be pretty quick and
straightforward to implement so we're a
couple streams in we're kind of finding
that like well it's not quite as simple
as I thought it was going to be uh as is
as is often the case with software in
general um but it I still want to like
explore the idea and continue on so
where we're at right now is I have a
database um where basically I have like
items in folders each item has like an
ID so here we have like item 1 2 and
three are the only things in the DB
right now and if we look at the metadata
along with this
database um we can see like oh each file
has like a name so item one is called
hello item two is called World item
three is a smiley face um and each of
these guys have relationships right so
there are relationships that's like one
relationship we have is I like
relationship one and it says that it
relates parents to children or children
to parents depending on which way you're
looking um and then we can store for
each item we can say well which
relationships are you part of
essentially and so we have this little
database tool that can like show those
things to us so I can like list the
items and I see I have item one and he
is a has a relationship of parent child
uh where he is the parent and The
Sibling is item
two um and that isn't represented in
like the source file system anyway but
once we mount it uh with our little
custom script like custom file system we
can look at the test Mount folder and
now we can see that like item one has
children world and item two has parent
hello um which is okay we're pretty
close here uh these guys are end up
being like empty folders but what they
really should end up being is uh Sim
links to the other items so the first
thing that I want to do today is like
quickly fix that I think that it
shouldn't take too long uh to fix that
and then uh when we get to the end of
that what we kind of want to do next is
um say we have a relationship of like
this item blocks this item and kind of
like a tree of work that is like real
that we're going to end up having is
like I'm going to use this to represent
my like image to text neural network
project and you know one of the things
that I might want to work on is I might
want to work on like porting the project
into like run it from like rust or C
then I might want to look at like
wism um so I can run in the browser I
might want to look at like simd to like
speed things up from there I might want
to look at like WM and simd and I might
want to build like a website
website but like all of these things the
only real thing that I can work on next
is this so we need to build like some
way to filter out the next available
items which should be as simple as
saying um show me items where they have
they are they have no parent
relationship right
basically this link doesn't
exist uh oh sorry this link doesn't
exist he can have children he can have
arrows pointing down but he can't have
an arrow pointing up so this we we'll
kind of delete and we'll say anybody
that has no blocked by we want to show
that um and I'm being careful here
because I think that I I think that this
is all doable without the
project uh code knowing that there is
such a thing as a blocks blocked by
relationship I'm kind of hoping in my
head that when I get to the end of this
I can use this as like just general
document storage cuz like anything that
has Rel like this is just folders and
relationships and I want to be able to
as a user put in any custom filter that
I find relevant um CU like something
that's bothered me about other task
tracking systems I've used in the past
is like the data is there and I can't
get what I want out of it so the more
that we force ourselves to build things
in the general way uh the more
flexibility I'll have later as well
which is pretty sick um so yeah that's
that's what we're working on today
that's what we're working on today so
let's start by just getting going with
uh adding those Sim
links um let's see let's see let's see
so there's been a little bit of
refactoring done to get things like in a
committable state since last stream
we've now kind of split this up as uh
there's this library that we're using
lib
fuse and he's written in C he is now
connected to this like C adapter
thing uh in Rust and he all he basically
does all of the like system and fuse
interaction that's his role now and then
we have like our like client
client and he handles like informing
this guy of what the custom attributes
of the file system are if that makes
sense so like any any like work that
we're doing related to our file system
kind of ends up in here client talks to
the
database uh these are split because in
theory like in the future we might want
to do like an HTTP server on this guy
and like set up a website or whatever
like the data is like its own thing and
we're working kind of like on one view
of the data but there could be future
views of the data that aren't this so
keeping them separate makes sense um um
and so anything that we do that's like
how does the file system look gets done
in this area and then we just like
forward out for like actually
interacting with the system to this
extra
thing um so if we are looking at Sim
links what the first thing we're going
to have to do is we're going to have to
say that the paths that are related to
our relationships are Sim links so if I
like Mount this
again and we look at children this is
flagged as a folder right now this needs
to get flagged as a link so that's step
one which
means when we iterate our
directories
we let's think let's think let's think
we the we parse paths that's probably
where this is going to go so we we get a
path from our program right somebody
says LS in a directory and which
directory they Ling is going to be
passed in here and based off the path we
do some like heris matching to check
where that should go right so if we have
like uh if we're in items items One
content we know that that's the content
for the item with id1 and if we're in
items items one
children something this should at this
point in time this means that there's
like a relationship where we have
children and every item in this folder
should be one of those
children uh and so I think that we have
that case here we have this things like
matches item relationship
folder and if we match an item
relationship folder we flag that the
folder purpose here is to present our
item relationships so really all we
should do here is wherever we determine
that that item relationship maps to a
directory um we should just say that
that should be a Sim link and it looks
like so one of the things we do with
that is we list contents in that thing
uh where we flag items as
directories and also when we get the
attributes of a path we ask if the thing
is a directory and if it's a directory
we say Okay directory otherwise we say
it's a file so I think let's just double
check that that's correct here if we
take this is dur function that we call
uh we can just kind of throw a take this
guy out of there and say in this case he
is
a if we say false here I think what
should happen when we Mount this now is
that we should show children as files
not as
directories I
think uh so we can go
to uh sorry
CD LS test Mount items zero should have
chilled
dren no zero isn't a valid ID sorry they
start at one so here uh we
have items one children oh oops we've
changed the the actual container of
children to a folder not the items
inside it so we were incorrect here item
relationships should still be flagged as
a directory because it's a directory
relationships okay um which means that
we actually are going
to uh have something thing uh item
relationships item relationship
relationship
side so this should be a singular
relationship I think who does this guy
come from matches item relationship
folder and he
checks
if he is a child of par of
items then we check if oh God item
third fourth so this is something like
items
ID
relationship
name sibling should be this
path okay which means that
somewhere we should be
checking if we're in a sub folder we're
not in the exact folder we want oh so
maybe this is a mistake matches item
relationship folder it could be that I
up
here um because here we're trying to say
like this folder is an item relationship
and we're saying if this thing is set
then it's
not
H let me double check that that's like
the purpose of
this so
here we have
items item relationships
I guess we don't really have a
distinction for
like oh okay yeah that's right that's
right sorry so this item relationship is
I am item one I have a relationship
parent child and I'm the parent side and
so in that means that this matches
function is correct and so now we also
actually actually have to create a new
path that
represents the sibling as
well um yeah that makes sense that makes
sense
so
here we want a
item
relation relationship
relationship sibling I
guess
and he is
I guess he doesn't actually care that
he's a sibling
probably he probably just cares that he
is a Sim link so we can call this like
item
link to a specific
item that seems reasonable to me so the
item relationships folder will return a
bunch of item
links that seems reasonable uh we
probably need like a link type
here as well
and I think that'll probably line up
maybe uh so here we currently have this
like is directory function and this
should now be
uh what
like entry
type
um I guess maybe we'll just call this
like get
entry for this path
and he will return our like dur entry
thing which is dur file or link with
their Associated
name
and then
what we
basically we say let maybe we just pass
the path in for any of these what is
where do we use this dirt entry
otherwise hum I take it back I don't
want to do it this way I don't want to
do it this way I just want to call this
a uh file type I guess we'll just make a
new thing I'm okay with that that
happens to be like duplicated with this
which is fine but we just won't specify
the
names sure sure sure
sure so that means this guy is going to
return now a file type
and then all we have to do is all of
these guys return file type
dur everything in the world right now is
a directory because we don't have any
files at all yet um in our custom view
we do have like paths that get passed
through um to like the original files in
the original folders but those aren't
handled by this section of the code it's
okay um
and now we can just throw on this extra
piece here that is if we have a path
purpose is an item
link we are
now a
link
easy okay all right hey man what's your
experience uh yeah I've been I've been
like in industry for like 10 years is
probably worked at like a uh
firmware company for security cameras
which was pretty fun uh I don't really
like security cameras that much but like
all of the work that goes into them is
like pretty interesting uh you get to
work on like you know system on of Chip
stuff like board you get like a somebody
like hands you like a circuit board and
then they go like please make it run
code now which is pretty fun um then I
worked at like another place where we
did like neural network stuff for uh
robotics like automated manufacturing
stuff both both pretty fun uh yeah
school for computer engineering so I got
a little bit of experience under my belt
but you know normal amount normal
amount uh here we're going to call this
get file type the
path then you currently employed uh I'm
taking a year off uh just to like you
know for fun and the thought is if I do
this for fun uh there's like two options
right one is that like the stream does
better than I expect and maybe one day
like it's like enough to sustain me and
I get to the end of my time off and I
say I'll just keep going or it's just
really good interview prep right
just talking about programming all the
time to you guys and having you
understand what I'm thinking it's just
holy I'm going to be like miles
ahead of my next interview it's going to
be
sick
uh yeah
so that's what we're working on right
now um okay so somewhere somebody was
calling is probably on the
like uh where was I looking you deserve
better coffee hey D dude McDonald's is
it tastes like milk and that's all I
really
need I shouldn't drink logo out like a
shill I should like mask it off
before I drink hide it in another cup or
something um okay somewhere somewhere
fuse mod probably I was calling iser to
decide if I should set the attributes of
this thing to be a file or a directory
and I guess now instead of calling iser
I say get file type
great and I say if this is a
file type dur well import this and we
say file type dur we do that
uh if it is a file type link or this is
file type file we do what we're doing
here otherwise we have a new case here
we have a file type link and I believe
the name for a link was like
s link we can actually check we do like
Man 2
stat and uh somewhere in here we can
look at if reg here okay here so here in
their example they say uh ifre is a
regular file sock is Socket link is a
Sim link hey steveo thanks for the sub
appreciate it we need some nice emotes
yeah dude okay so I don't really know
I'm not a chatter I uh I'm a twitch what
is it what do they call them lurkers
usually I don't really type in people's
chats so I don't really know like what
people expect to get out of Subs I know
emotes are part of it is there like
anything else that I'm supposed to be
doing as like a streamer to get you guys
to like not feel ripped off if you press
that
button uh okay so what we're doing we
were in mod and we were where why can't
I foreground foreground what the is
going on why can't I get back into my
Vim oh cuz it's over here that's why
that's why uh so we were looking
at somewhere we were supposed to set if
Link in our client
mod please write our names on your body
do you want me to like take my shirt off
and like do it right on my chest
if
link is that emac no it's Vim oh I think
somebody else asked earlier where my Neo
config is um and I forgot to say it just
doesn't exist sorry man uh it's not not
on the internet why is if link not there
hello if Ln K of course they don't put
the i in link why would they you can't
spell it whole words we need to be
limited to one two three four five
characters um
and I think 644 is probably reasonable
for a link I actually don't know if I
like ln- s test to shell. n and then I
oopsies other way shell. next to test
and I look at the permissions on this it
looks like they're just like
maxed
out Max the out so I guess I want 7
S7 for links because I guess the idea is
that it you can view the link if
you want you still won't be able to view
the file contents if the contents the
actual thing that you're linking to
aren't
set no no emotes is it for me even when
there's more of a link to the stream
like thinking about something or writing
something of course want stream got
it push your Neo config bro uh so it
lives like in my DOT files for like my
whole
system and I don't really
like I don't really trust that there's
nothing sketch in there that I don't
want to like uh leak to the world but
like my new confi there's nothing crazy
in there it's like mostly default like
the plugin list is kind of interesting I
guess but like what most of what you see
here is just like
telescope and language servers which is
like really easy to find find stuff on
nothing too crazy nothing too crazy and
I guess tree sitter but I don't know if
like treesitter is like necessary it's
just like prettier syntax isting me you
know uh okay so
uh you just want to see how to set up
rest support oh all that is is uh we can
actually show that it's worth it config
and Vim in it Lua all that is
is here I call into like LSP config rust
analyzer setup that's it LSP config is
just like a
like like a repository of language
server
configs um and just like for each one
that I have like an executable for and
just bang it out easy
peasy um okay what was I doing I was
looking at adding item links
to read your output so one is that the
par the path path
parsing has to now say that I have uh we
have to return a path purpose of item
link if we match an item link folder so
I guess that'll just come down here
we'll say else
if
uh Su Item ID is equal to matches item
link and we look at the path and the
DB um and I don't really know how we're
going to do this yet but in that case
we're going to return an item link with
the item ID that we're linking to okay
we need to create this matches item link
thing so I guess for now we'll say
function matches item Link and he's
going to take in self and path no no
self here just a
path and the database that we're working
from and he's going to return a bu
representing if he's true or not and I
guess if we just take the path
parent and we say that uh
matches item relationship folder of the
parent I think that we then know that we
should be an item
link I
think uh this should actually be result
bu I guess because this can fail so he
returns he can fail with a query error
of the DB
easy
and why is he still not happy C
check files system seem complex how did
you learn to do this I mean I knew that
like I knew that fuse
existed and I knew that like I can
interact the file system and I just made
a guess that it wouldn't be that hard
and I think so far it hasn't seemed that
hard like it's there's a bunch of like
small Concepts that you have to build up
from like oh I need to list a directory
but like it it's nothing too crazy right
like just it's just uh I think
interacting with the operating system is
kind of the same as interacting with any
single like Library you've ever used
right there's like unknown behavior and
a list of functions that you're allowed
to work with and you just have to figure
out like what the are those
functions supposed to do and so I don't
think that like I've never like done
this
before this it's just we're kind of
learning as we go learning it as we
go um this doesn't return result that's
why this is supposed to return an option
of item
ID um um and so here what do we get we
get back a relationship that we match
here so we can say if this is
none we return none because our parent
our parent must match if our parent is a
relationship folder then that's the only
place where like this Sim link can show
up right now later we're going to have
to like amend this to check other things
uh but for now we know that this is all
we can return and this can fail so we
throw a little question mark on
him and otherwise for now I think if we
just type none here it should
compile
and that will give us a little bit of a
somewhere to start from path. parent
doesn't exist for some reason what the
he returns an option path oh I see
so uh we can say let parent is equal
to uh parent
is you're say the parent should be
something some parent is equal to path.
parent
otherwise uh we return okay none because
the path if we have no parent that means
that we shouldn't match easy easy is the
game on the right side running in real
time did you make it when was that uh
yeah there's a stream if you go to like
there's a link YouTube and one of the
playlists on there should be writing
this thing um but I will warn that I
think that was like the first set of
streams I did so I actually don't really
remember if uh they're any good but it's
up there uh I think the code I never
pushed it uh but it's not it's nothing
too crazy it's just like
gdau gdau procedural maze generation
with like mesh libraries and grids and
then camera movement so if you've done
like any Game Dev should be pretty
nothing nothing crazy you could probably
bang it out in a couple days
um okay so here we have our parent now
we can just say parent like this and
this should compile cargo
check cargo check he doesn't compile uh
why why why why why why uh 339 not found
this ah so here we said if we match item
link um but I guess there's a case where
this could fail and so this like
show of a like if statement is going to
start looking even uglier so I have to
say that uh we have an error here and we
have parse path
error and I
guess we can call
it check item link match let me see I
fail to check if
item fail to check if item
link match that doesn't really sound
like English when I read it out
loud but uh it it's close
enough check item link match there we go
and we throw a question mark on there
and
then
uh what are we missing
here matches item link why is this
bitching result option item id K so this
should then I throw a question mark on
here so should put an option item ID
off man what am I missing item id
oh because I forgot to put let if let
some of course of course I just have to
write the right
syntax okay we're close um we have to
cover the case where path purpose item
link
is provided as an in uh to the list
directory function um I guess this
should just fail this just should never
happen um do this return error reader
error okay and I guess we should make
sure that we have one that's like not a
directory not a directory an error
reader called on non directory okay easy
uh I want a capital D here and then down
here we can just say that if somebody
calls read draw item link we just
say uh return
ER what is this reader error not a
directory okay boom boom boom
boom
easy does this compile
now we're
close uh we have in our line
73 nope line 134 here they're saying
that I'm missing a
case
aha so here if I'm listing things and I
find a
link I just put the name there and I
guess here we're supposed to fill our
like stat buffer of these things like
we're supposed to say that
uh get attributes of the thing we return
we're not filling them in right now
which is like a little bit of a mistake
I guess we can just fix that now or we
can write fix me and not fix it
now
perfect because I think that what
happens is when we call LS it actually
kind of ignores the stat buffer returned
from the read directory call and it
actually like calls get attributes on
each thing and if it those conflict it
just uses the ones for get at so that
should be fine and I think the last last
piece here
is we just have to replace uh this
folder when we iterate item the item
relationship folder like I.E like the
children folder
um right now he's like finding all of
the siblings and he's like returning
them as
directories I think we just write link
here
and there's a good chance that this just
works now I give it like
maybe uh maybe like a 60% chance of
running col
correctly let's see it so we can go to
CD test
mount CD oh no sorry we just want to
like LS test Mount items one
children
okay so this is still not working
correctly so he's saying that that's an
unhandled path
actually unhandled path thing so that's
kind of interesting where does that log
come from
unhandled
path
looks like
here uh so he's probably just not
matching as a link
here um oh
because this probably we never actually
checked uh we never we never figure out
how to like link the ID back uh so let's
just quickly say uh log
error hello we have to fill this in
dummy
and maybe we put in the path
here and we should see now if I do that
same LS we have to fill this in dummy
for items one children World perfect
perfect perfect perfect
perfect okay so now all we have to do is
like resolve this guy
back um and what does that mean so we
know that we have this
is items ID
relationship item name is what we're
kind of showing here which is kind of
because there's no like reliable
way for us to go back from item name to
ticket ID cuz like you could have two
items that have the same name but are
like distinct in some way right if you
just happen to create one like in the
context of some project so
for now I think that we will just live
with that probably the correct thing to
do is to like do some sort of name
resolution if you have conflicts you
just like put a two in front of one of
them or something um and then we would
have to like correctly figure out which
one it
is
um but for now we'll just uh not handle
that case
gracefully and that's probably fine uh
we need some way
to basically find a ticket by
name and maybe we can like reduce the
chance of the
Collision uh
by also checking the relationship so
here we know that we we know a few
things we
know uh our
ID we know the relationship
name which like technically could also
have the same problem as with item name
and we know the sibling
name so I guess we can do a database
query of just that just matches all of
these
things um so we can say
what Pub
function uh Item ID from sibling
relationship name or something
sure uh and what are our things we have
uh sibling is an item
id uh relationship
name is a
string and uh item name is also a
string okay which is going to return
result of an item
ID
or maybe like a quer error to start and
if there if it ends up being something
that could be more complex than that
then we'll return something
else
okay
so what does this look like I guess we
have a statement that we're going to
have to prepare so we say let mute
statement is equal to self connection
prepare and it's like what
select ID from the files
table where
um and we have what like name is equal
to the first thing that's like the first
part that covers this
constraint
um but what about this
stuff so here we need to look at
relationships that
involve our
ID
I wonder if there's can you like do this
in like one
statement we we want like because the
problem is that uh for
relationships there's not like a
onetoone
mapping
of ID to relationship it's like me one
to many so I think there's actually like
a join that you can do in SQ light that
will basically duplicate the left side
for every item on the right side that
matches I think inner join
maybe SQL in join records records that
have matching values in both
tables
uh inter join categories on this equals
that
um does that maybe it's the another one
let's see uh
maybe SQL one to many
join uh what do they do inter join
yeah but that doesn't seem like it's
what I want Ty typo and sibling by the
way in function name thanks we'll fix
that
uh maybe that's right I guess we'll just
have to test it we'll just have to test
it because I don't know what the
I'm
doing
um so let's look at our
metadata
and I guess right now we only have
uh one relationship per item so I guess
let's just add an item
relationship for id1 for like something
else to work with so I think we have
like DB
tool add item
relationship between one and three
doesn't compile right
now just comment this out siling sibling
nice okay so now when we open this in
sq8
browser we should see item relationships
we now have two mappings for item one
and so now we can just figure out what
our thing should be so from or
select
star from
files iner
join
item
relationships
on uh
files ID equals item
relationships from
ID oh jeez but I can also match the two
ID so I just put like an or here or
files ID is equal to item
relationships to ID does that give me
something
Saye uh oh okay okay wait wait that that
might be right
where files ID equals
one okay yeah sick okay so we do have
the like duplication of the file ID for
each relationship so that's perfect
that's perfect that's exactly what we
want
and
uh let's just throw out a files ID
equals 2 here just to double check hello
backspace why can't I backspace
this why when I press play here that was
weird I don't know why it was
stuck okay yeah and so it does match
with both from and two okay so that
looks right and I guess we actually also
have the relationship name we want to
want we want to match there so do we
then also do a left
join
um
on
relationships or item
relationships item
relationships ID is equal to
relationships
ID uh which
left join
relationships I think that that does
what I want no
no such column item relationships
ID ah so this should be a relationship
ID and that should be a one toone
relationship so I think we're chilling
sick okay so that gives us all of the
things that we want per row that we have
to match
from sick sick sick sick sick sick and
and all in one query which is auggies oh
God I should never say that God damn
it
um
Okay so we've got kind of like a
template for something that should
work and now we just have to punch in
the pieces that we
need
so we have
have oh I guess we wanted to add some
more filters
there uh because we also want to do the
filtering here so we can just assume
that every piece is what we
want uh so let's comment this out
comment this out and go back into SQ
browser uh SQ
browser
and I think all we need to do here is we
want to do where files ID is equal to
one
and item
relationships
uh I guess we don't care about the do we
actually care about the item
relationships maybe not what are the
things that we're trying to match again
we have relationship name and item name
okay so we have so and files. name is
equal
to
uh oh
oh we actually want to join on ourselves
again is that true so we have we
have our file ID and then we have like
other file
name so we want
like us F us file
relationship them
file is like the things that we not we
want so that we can match on us file
dot
uh
ID relationship
name them file
do
name uh yes yes yes and we shouldn't
call assum we should say that um we're
ID we have our ID
and we have sibling name that's more
clear to
me which means that we actually have to
join on ourselves as well oh Jesus
Christ uh okay so we're close we're
close so then
we this gets kind of wonky
though because we don't know if we're us
or them here we don't know if we're like
the from or to side of the
file uh but I guess
that's maybe I'll just do this in
multiple queries trying to crank this
all into one SQ like query is like
probably technically faster but it's
getting really
nasty getting really nasty so instead
let's just do this in many um we'll just
do it me
it uh uh okay so in what's like the many
call way to do this we
say
find all of our
relationships filter based off
relationship
name filter based off sibling
name have you considered using drizzle
omm never heard of
it
drizzle
or lightweight what like what is it o RM
stands for something
clearly relation object relational
mapping so it's like some sort of
wrapper around databases that
like make it easier to work with I
guess yeah I see I see I see I
see um for now I mean I feel like I
should be able to like
Flex my SQ light bones enough to get
this right and it makes it in fact
harder to work with that doesn't
surprise me I feel like the abstraction
lers I would imagine are usually really
nice because they let you like switch
out the database back end without having
to like re code anything um but I'm
pretty tied to sq light so I'm not
really worried about
it um okay so first we need to find all
of our relationships so uh uh that's
just
select
relationship
ID um I guess we want all of our
relationship
siblings that seems reasonable to me so
we can just do that in two calls one
where we
select
uh
I guess we're kind of missing a key part
here in that we know which side of the
relationship we're
on
uh side is a relationship
side that actually simplifies that like
massive query a lot because now we know
if we're on from or to so we
have okay okay wait wait this actually
might work now it might
work
so select star from files injoin
relationships item relationships that
makes sense now and now which what which
of these paths we take uh depends on
which side we are so we can do something
like match
side and if we're
relationship if we relationship side if
we are the
destination then we know that we
have a
uh files ID equals item
relationships uh to
ID yes
yes
okay
and then we know that we're
matching
uh the
files
on files. ID is equal to item
relationships from ID yeah yeah yeah so
now we have our simplink and then
there's like a left join as I think join
as uh
esite can you like SQ light rename table
for
query for query I just want to like
address it to something
else or sq light self join
maybe so I just want to know
like there's a way
to Aha join employees with the Alias
after so left join files on them files
on us files ID or them files ID equals
the from ID yeah yeah yeah okay cool and
then we just invert this for if we're on
the source
side so us is now from and them is
to yeah
okay I think this makes
sense
um so inter
jooin this inter
jooin
uh item
relationships on
this and this
is inner join item relationships on
that
okay
so this is now the join
string and then then we're getting there
we're almost there we're almost
there we
have this is still
all the
same uh select I guess it's not
everything we have uh what do we want to
extract from this we just want them
files
ID
yeah
okay so
format this plus the
Joiner and then we can just shove in our
where and we throw in our the things we
care
about so uh us files. idsal to the first
thing them file Fame is equal to Sibling
name and
relationship
relationships
dot oh uh we need to know
if we need to match depending on which
side of the relationship we're on so
we'll say let relationship where is
equal to match
side and if we are the
destination we want to match the
relationship
source so relation ship.
from ID isal there's another join
in here oh my
Lord oh no no no it's fine it's fine
it's
fine I
think item relationships relationship ID
yeah yeah yeah yeah yeah yeah yeah yeah
so
relationship
Dot
from I think that's the name of thing in
the
table relationships from name it's
called
um
okay from name or if we're the source we
are matching the two
name Source missing s yeah thank
you
Jesus uh so where this and this and
relationship where oh my
Lord
okay surely that's not
right um but we can print this for now
and run that manually and just see what
comes
out uh so I guess just replace the
format with a print line
here and just see if that's reasonable
so we can go to our DB
tool
and uh for now we'll just
everything
and yeah
everything
we're not doing any of this and all
we're doing is getting the DB
from test
DB and then we're just going to call DB
find nope what do we call this
disgusting
function Item ID from sibling Item ID
from sibling relationship
name all
right and this guy is unimplemented down
here
all right
so we have item
id
one what else do we have relationship
side uh we are the source we are the
parent the relationship ID is
one okay and the
thing that we're matching with is World
cuz we're hello we have Hello World
hello is the parent world is the
child and I guess uh are we also
matching the relationship name we
are not the relationship ID so this
should be which side of the relationship
are we on we are matching children cuz
we know that we have
children
okay
Jesus
Christ let's just run the DB tool and
see what
happens select them F okay let's just
run this in SQ browser and see what it
is
about um SQ light
browser xsql and we just replace this
with uh we didn't actually pass the
parameters in so us files. ID is one
them files name is world and
relationships from name is
children this is wrong by the
way we should have two name in here not
from name so that's that's
inverted
uh
uh there we go from name here two
name
there and we run it again
all
right SQ like
browser and we should probably just
leave this open so we'll run we'll
redirect everything to Dev null to Dev
null so it doesn't up my terminal
and then run in the background all
right open
recent this guy execute SQL we paste
this here and so it should be us files
ID
is um one them files name world
and relationship's two name is children
and if I press play here he doesn't like
that there was a bracket
somewhere here there's an extra bracket
there shouldn't
be no such column us files. ID from
files us
files no such column relationships to
name so do we not join relationships
ever we did not left join relationships
on item
relationships I uh relationship
ID equals relationships
ID hit
play okay well we got something out of
that so that's close so we made three
changes
there I already forgot them but we'll
find them so one was a bracket that
shouldn't be there this guy he shouldn't
be there another one was that we forgot
to rename file to us
files and the last piece
was we forgot to join
relationships
um join left join relationships
on uh item relationships relationship ID
is equal to relationships ID what a
show man what a
disaster
I bet you this is an indication that I'm
doing something horribly
stupid um but you know we live so us one
them world to name
children play and we got id2 which is
the world so that's good that's working
so far and so now let's just run the
inverse of this so we are item two now
we are the destination we are looking
for parents and we're looking for
hello
and let's just run the same
and here we have us files ID 2 them
files name
hello and from name relationships from
name is
parents boom
baby okay
so I thought that this was going to be
quick but this actually turned out to be
a massive pain in the ass but I think
that this that this like query is
correct so we'll say let query is equal
this and then we can say self.
connection
prepare
query onw wrap for a
second prepper
prepare and we need to borrow query okay
uh let statement is equal this then we
say
statement statement
query
map and we pass in the things we care
about so we have one two and three which
are ID relationship name sibling name is
that the order that we did them in
relationship name was the last
one so we have
ID and I think we we can use a macro
when these don't have the same type Russ
qite pams yeah it so we have the item
ID followed by The Sibling name followed
by the relationship
name all
right and then we run our query
map uh so I guess we're just mapping the
ID so we just have row here is the thing
that we have inut here we just say row.
getet
zero and we say that the ID should be an
I64
and we return okay item id
id sibling name SI siling sibling name
nice and this should be
mall
and this should probably be an unwrap
here we'll fix it later and then query
dot
next and this should be the first thing
and if there's a second thing then
there's a
bug um so here we can say if second is
some uh we have some sort of error but
for now we'll just Panic multiple items
matched brownie
face and if that's not the case we just
first all
right and should be probably okay first
I
guess what is the type of the thing
first is option result ah so I think
that there's like a
trans
transpose to switch to go from like
option result thing you can type
transpose to turn that into result
option thing uh so we just transpose
unwrap for both
these because we want to make sure that
they
succeeded I don't know what happens when
you transpose on a none it must go to
ok9 so I think it's fine it's fine
um so now first is an option Item ID and
why is this using a
problem seems fine cargo
run expected item id found option item
id aha so I guess there's always the
chance the option the item doesn't match
and returning none seems reasonable
there okay so now we don't crash and
let's just print out what we get print
line uh he doesn't like that because it
needs to be format with
debug oh hell yeah baby so item one
works and we'll switch this back to try
to find item
two so I I guess if we do parents if we
try to match with parents this should
fail because it should be matching
children but if we put children
here matches fine sick and if we change
the name we like up the name of the
task oh baby okay so this is something
that for sure should be unit
tested like
mad because there's like all sorts of
ways this can
fail um but for now probably good
enough um okay so we can go we've that
took a while much longer than I thought
it would but we've now
resolved the ID of a
sibling based off of these like her
istics so we should be able to go back
into our client our fuse client and here
we can just say
DB uh Item ID from sibling relationship
ship
name
uh
and we actually get all of the things
that we need from this like matches item
relationship folder so we should do here
instead of this like if none we should
say let relationship folder is equal to
this and we can say let some
relationship folder is equal
this else
return uh oops is the else goes here
return okay not nothing fails but we
didn't
match and so now we can just call into
our database and ask hey could you
please
tell us what our sibling is
based off the
relationship
folder first thing is the item
id uh the second
thing then we have the the
side we have the relationship folder
dot
ID oh that's interesting we actually
grabbed the ID from
this
okay and then the sibling name so we
say uh let
sibling name is equal
to what it's the path
file
name and here we can just pass in let we
just say
to unwrap
toer
okay and we're close here except that we
actually are using the relationship name
here instead of the relationship ID but
we can just go relationship ID and say
this is a relationship
ID
and then instead of trying to match on
relationship
ship's
name
um think let's think about this
relationships ID is equal to
3 no matter
what relationships
ID equals
3 which is kind of wrong actually we are
we don't actually have this piece of
information but that's okay it's fine
so this now ends up just being instead
of relationship name relationship
ID okay and then does this compile
now I think it
does we unwrap here no he doesn't
compile Caro check what's he complaining
about sibling name expected stir found
option s so we just assume that this is
castable for
now and uh let's go back into our DB
tool test and just instead of passing in
children we're going to use relationship
ID
one and double check that both paths
still work so when we're trying to match
that that worked and if we're trying to
match from world to
hello we should get
back okay good everything's still
working which means that this should now
return the right thing which
means um I think we just return
this and maybe we just return like this
oh hell yeah
baby
okay okay okay okay I wonder if
everything just works
now seems possible
LS to do or test
Mount items
one
children Okay so we've got the links in
there they're correctly marked as
links they just don't have the function
implemented to read the link we're so
close we're so close let's go
baby uh
okay so here we just have to implement
the readlink function which I think I've
seen in here as
readlink yeah it is okay so here we just
kind of Slam in a unsafe excy
function read
link and so we just quickly man to read
link to see what his parameters are path
name buffer buff size okay um so we have
path buff buff
size and what's his return value
he on success Returns the number of
bytes placed in
buff on error negative-1 is returned and
nno is set to indicate the
error okay
so first thing that we do when we make
these calls is
we extract our
client and then we say hey if this is a
p we have this macro that basically says
like hey client is this
like something that you handle or is
this something that the OS handles for
us and so in this case it says like if
let
some R uh pass through path is equal to
we should call this pass through
path if let's some pass through path is
equal to pass through
path then we should just call CIS the
system implementation of R link for this
this thing so we have rust to C path
pass through
path and then we just pass the other
pram buff and buff
size and this guy is going to be like
he's going to like return an error in
some cases so we have another macro here
that says C call ER no1 which basically
says like hey execute this function and
if it returns netive 1 return negative
nno otherwise return the
return so we can just say uh
use thisis read link to like fix some
like macro
and then I think it's just
this so we call read link with these
arguments and we return the
result okay uh
otherwise we're close this expression
has
Type path buff oh does this
guy
oh this is actually what I want
client get pass through
path
um C to rust path path okay so that's
close and then we match pass through
path uh I guess we have
um if this
succeeds we just pass it through and if
it
fails uh we log an error and return Nega
1 where negative 1 is actually not
correct here but it's correct enough uh
for me for now so we'll say log
error invalid uh failed to retrieve pass
through path do to
e
okay then this is still
fine uh we actually need to do this as
i32 uh nope we just return this as i32
here great and this needs to be as
pointer wonderful okay so now we just
have to handle the case where we are in
charge of resolving the link and so here
we can say client
resolve or maybe call read
link
on the path again sure let rust path you
see to rust path
path this we call rust path here and
then we call rust path down here as
well and then we say
let link is equal
this and then fix me do something with
the link maybe we'll write unimplemented
here so we'll crash because we don't
know what we're going to do yet it
depends on what the client returns which
we haven't figured out
yet uh so we have this client and we now
have a new function that's similar to
reader except he's called read
link and I don't know what we want to
return here or if it failable so let's
just kind of like start typing and see
what happens to happen so the first
thing we're going to do is we're going
to parse the
path which is can fail
actually um so we should check
that uh I guess for now we'll just type
unwrap here cuz we we haven't really
decided it might we might end up seeing
that there's like several return types
that we have to like meld together so
we'll just kind of unwrap and then deal
with air handling at the end I think
oops what did I just do there we go
um so then we can just match this
thing
um and we can say
item link is equal this and if we have a
item link if the purpose of our path is
to link to this item id then we do we
just return the we continue on with the
item id uh otherwise
though we uh return an error I
guess but we'll write Panic for now
because they don't want to deal with
that so Panic um item is not a
link
okay and then I guess we just return a
buffer that is what we want to like the
link that we want to link to so we have
um basically items folder
join Item
ID and I think that's
it um this is do0 and join is not found
because it should be a path new from the
item
folder and so I guess now we find out
that this is going to be a
result uh that is a path buff is where
he returns and the airror type is just
going to be the error type of pars path
no there's going to be an additional
thing so there's going to be a new error
type here um called read link
error okay and so now we just have to
implement the read link error
so Bo boom this is going to be the same
here we have an OP we may fail to parse
the path which is the first thing or um
we have not a
link uh error item is not a
link easy and so here we return
ER read link
error not a link boom and here we map
the error to read link error parse
path easy easy easy and this is read
link error not read their
error and then we wrap this guy in okay
I think we're
chilling looks like we're chilling so
now we kind of know what this is going
to look like and we go back to our mod
here and we can
say if this
fails
uh we have okay V goes to
V and eror E goes
to log error failed to read link due to
e otherwise and then we return Nega one
I guess which is still wrong but
it it it
it um and then we just have to put like
basically meem copy the link into the
buffer what happens if the buffer is too
small
um e bad f e
fault e access e inval buff size is not
positive insufficient Cal memory does
are any of these like buffer too
small we return value views calls return
number of bites if the return value
equals both sides then truncation may
have occurred okay so we just may we
might
trunade so it looks like we call what
stood M M Copy M Copy is there no copy
copy
copy is there no mem copy in
Russ there must be pointer copy that's
what all is stood pointer copy yeah yeah
yeah yeah yeah yeah yeah and so we take
our link and our link is currently a
pass buff so we want to convert this
into an OS string into encoded byes so
we just get a buffer
bytes so let
link we'll just do this it we don't
need the old one
anymore um and then stood pointer copy
link
dot uh is this destination or
Source St pointer copy Tak The Source
first so Link at as
pointer
buff and then we just need the size so
let copy size is equal to link Len
Min buff size
boom
boom arguments of function are correct
you uh cuz this
is uh he doesn't like like the i8 u8
thing and does this return how many
things were
copied no but I can just write copy size
here um try and to expect copy size did
not fit in
i32 which should never
happen all right I wonder Well's test
Mount items one children
function not implemented because we
didn't actually hook it up so we need to
say Ops read link is equal to Su fuse
client read link which is not what I
named
it I just named it read
link run it again we forgot a
semicolon
here we Runner
again numerical result out of
range
interesting
why is there a coal in
here oh because this smiley face is a
up name can we LS children
World okay so what doesn't he like here
use bad error value
eight okay so we have some logging to do
I guess to figure out which path this
took to
fail so let's just go into this read
link thing and we'll just
say uh well we know we didn't get here
because we didn't see this a log we
might have got here so we're going to
say print line resolved as pass through
path pass through path so that could
indicate some
bug otherwise we should see this fail to
read link otherwise we got here so then
we'll say print line uh resolved link
link
link and that should give us some
Clues okay so we did resolve link to
items
2 to-dos can have child to-dos well
child is like just the relationship
we've created initially what I'm kind of
imagining right now uh that the I'll
have like a parent child relationship
for project
so everything within a project will be a
child of that project and then I'll have
block blocking
relationships and then each thing is
like each item could be have like
multiple things in it right like I could
it's a directory that could have like a
note with some pictures you can imagine
right you can imagine taking some
screenshots and wanting to capture those
so that later you can look back and say
oh this is what it looks like at the end
um in the same way that you might want
to like upload a photo to your ticket
tracker on J or something right
uh okay so the resolved link is actually
working and it's just the return value
he doesn't like that I returned eight
here so I guess maybe even though
readlink claims that I should
return the number of btes placed in
buff it's possible that fuse does not
want
that so let's see what the is he
saying read link read link read
link I I kind of just made an assumption
that's the same the buffer should be
filled with a null terminated string
okay so that's surprising the return
value should be zero for Su why
the all right it's fine it's fine it's
fine it's fine all right uh all right
all right all right
so here we return
zero and we actually need to do uh min
buff size minus
one
and because we need to stick a null
Terminator in
there and so then we say copy size +
one buff add copy size plus one is equal
to
zero to null terminate
him uh yeah
no just copy size not plus
one because copy size is one is the is
the length and the index for that is
like one off yeah yeah
yeah okay let's try
that LS we're close what does he like
now wait wait wait that's right isn't it
he goes to SL item SL
2 which is test
Mount items 2 so I guess that he just
doesn't
like the Sim link is not relative to the
root of the file
system which is kind of
uh which means which means which
means which means just when we read the
link here we just need to
um add on the root of the DB
so uh FS or self
DB
rude no that's wrong too it's not it's
not the root it's the root of the
mount and nobody knows what that is
right
now
gross oh that's so man
I guess it could be a relative link if
it's a relative link is there an easy
way
to retrieve that
here or do I have to like is there like
I don't really want to implement that
but I guess we can we actually that's
that's not too hard actually because we
should know the path that we're getting
in so we just have
uh print line
path we should just be able to go
up
until uh we get to the roote and then
TCH on the
rest
uh oopsies
LS this yeah so here we have items one
children world and we should just add
dot dots until we get to the very
top you want to convert relative to
Absolute no the problem is that I have
absolute but like I have the thing as
items 2 and I need to convert that to a
path relative to input path which is
fine it's fine we can just say that like
let output path is equal to path buff
new and we say
uh let's see let's see let's
see
while let uh path.
it yeah
do length
count so say n let N components is equal
this for I for nothing in n um
components output path. push dot
dot
okay
um
okay
then uh we have the items
folder but it's relative to the root so
we extract a bunch of it output path
push this
is it like
this how do I oh it's the dot dot in
this language
right
um
okay
then output path push item id02
string Jesus and then we return the
upper
path okay and and cargo check now so
itemer doesn't have a sign time I put
like a little % here
easy and then I run
this and I LS the test
Mount uh so we have one up one two
3 4 1 2 3 4
five that's not right that's not right
at
all why is that not right because we
have item
one children
world so I'm going one too
far I
think two too far maybe that make
sense let's just double check I think
it's
two hell is this oh baby let's go so I
go up one
two three items to does that
work yeah baby okay and the parents go
back to hello yeah yeah yeah so I can go
back and
forth from Hello
children wait does that actually
work
wo we did it
baby God
damn that was a lot harder than than I
thought it would be like a lot
harder um cuz I thought that that would
be kind of quick that's kind of funny at
the end of last stream I was like
there's no way I'm going to do
this in five minutes and then today
before I started I was like maybe I was
wrong maybe I could have done it in five
minutes and then I started I'm like nope
definitely not five minutes
um okay that's pretty sick um there's a
lot of like cleanup to do there there's
some like unit testing and aor handling
stuff to resolve
um but overall I think that's like all
of the interesting work pretty done and
I'm pretty happy with that I think a lot
of the complexity is probably coming
from the fact that I'm resolving by name
here like a lot of that was just spent
doing like DB lookup we got 20 minutes
what to do now uh well I think this is
why I give myself some buffer I say that
I'll stream for like one to two hours
because uh it just means that this is
kind of like a good this is a good
stopping point I think starting
something new would take over 30 minutes
I think we're doing all the cleanup and
stuff is kind of boring so I think I'm
going to call it there uh thank you for
watching guys this was fun uh if you
like what you saw I stream most days at
around 1 or 2 o'cl Pacific time and I
stream for like one or two
hours uh if you don't want to watch live
um there's a YouTube link in the twitch
description that will link you to the
vods for that they go up for almost
everything I think there's only one that
I didn't upload
ever um and if you're watching on
YouTube and you want to come say hi
there's a twitch Link in the YouTube
description um there's a Discord in the
twitch description as well for if you
want like announcements of when I'm
going to go live just like a little
ahead of time as well as like you could
like talk about programming and in
there if you want I don't know um and a
GitHub Link in the twitch description as
well where this code will eventually end
up thanks for watching guys and I'll
catch you on the next one bye