Re: [sqlite] Custom aggregate functions in Tcl

2019-01-31 Thread Andy Goth
I read some more about window functions and now see more clearly that they
are an extension to aggregate functions. Now I understand why it makes
sense to have a method name for both aggregate and window functions. I'll
also go ahead and put window function support in my code next chance I get,
rather than wait until I'm totally solid on aggregate functions.

On Wed, Jan 30, 2019, 13:59 Richard Hipp  It seems that you distinguish between the xStep and xFinal methods by
> the number of argments.  xStep as 1+N argument (where N is the number
> of function parameters) and xFinal has just 1.
>
> Dan suggests (and I agree) that this will not extend well to window
> functions.  It might be better to have an initial argument that is the
> "method" name.  xStep would 2+N arguments where the first argument is
> the string "step" and xFinal has 2 arguments where the first argument
> is "final".  Then when you go to add the xValue and xInverse routines
> for window functions, you will have a convenient way to distinguish
> those calls from xStep and xFinal.
>
> On 1/30/19, Andy Goth  wrote:
> > On 1/29/19 1:15 AM, Andy Goth wrote:
> >> I wish to define custom aggregate functions in Tcl
> >
> > Initial implementation:
> >
> >
> https://chiselapp.com/user/andy/repository/sqlite-andy/info/e0689f05d1f8792d
> >
> > Sample program, intended to be run from the root of a built SQLite tree:
> >
> > #!/usr/bin/env tclsh
> >
> > load .libs/libtclsqlite3.so
> >
> > sqlite3 db
> >
> > db function incr -deterministic {
> >
> >  apply {{arg} {
> >
> >  incr arg
> >
> >  }}
> >
> > }
> >
> > db function list -deterministic -aggregate {
> >
> >  apply {{state args} {
> >
> >  concat $state $args
> >
> >  }}
> >
> > }
> >
> > puts [db eval {
> >
> >  SELECT list(column1, ''), incr(42)
> >
> >FROM (VALUES ('#'), ('#'), (' c '), ('\'), ('\\'), ('{ xx '),
> > ('}'))
> > }]
> >
> > db close
> >
> > # vim: set sts=4 sw=4 tw=80 et ft=tcl:
> >
> >
> > Here's the output:
> >
> > {{#} {} # {} { c } {} \\ {} {\\} {} \{\ xx\  {} \} {}} 43
> >
> >
> > Notice that the first # element is brace-quoted and the second one is
> > not.  This demonstrates TIP 401 compliance (http://tip.tcl.tk/401) in
> > recent Tcl.
> >
> > Before I can call this project finished, I need to update the test suite
> > and documentation.  But I didn't want to wait for that to release the
> > code I've already written, so here you go.
> >
> > As a separate project, I would like to improve the Tcl script dispatch.
> > For several reasons, safeToUseEvalObjv() doesn't really meet its stated
> > goal.  I have a lot to say about this but should wait until another time
> > to go into detail.  Let's finish the aggregate function project first.
> >
> > Another good follow-on project would be adding support for window
> > functions.  Before I can take that on, I need to gain some experience
> > using, let alone writing, window functions.
> >
> > --
> > Andy Goth | 
> > ___
> > sqlite-users mailing list
> > sqlite-users@mailinglists.sqlite.org
> > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> >
>
>
> --
> D. Richard Hipp
> d...@sqlite.org
> ___
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] "Pickling" an in-memory SQLite database.

2019-01-31 Thread Thomas Levine
If sqlite3_serialize and sqlite3_deserialize are not exposed in your bindings, 
I suppose you can do something like

with NamedTemporaryFile(mode='rb', prefix=prefix) as tmp:
c = sqlite3.connect(tmp.name)
# Do stuff.
c.close()
serialized = tmp.file.read()

where "prefix" is a RAM filesystem.

sqlite3_serialize and sqlite3_deserialize are better though.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] "Pickling" an in-memory SQLite database.

2019-01-31 Thread Shawn Wagner
sqlite3_serialize() and deserialize would work:
https://www.sqlite.org/c3ref/serialize.html

On Thu, Jan 31, 2019, 4:47 PM Randall Smith  Hi, guys.
>
> I have an application that allows me to embed a (potentially large) block
> of data into its application file at close, and read the block back on
> open.  It would be convenient and attractive for me, for a plugin I am
> writing for this application, to be able to use an in-memory SQLite
> database, and then squirrel the DB away with everything else in the
> application file.  That way, everything would be stored under one roof, so
> to speak.
>
> My question:  Is there a good way to "pickle" a SQLite database into a
> block of bytes for storage, and then "unpickle" it later for use?  My
> fantasy is that this could all be done in memory so the file system does
> not have to become involved.
>
> I feel like I am missing something obvious here, but can't quite come up
> with it.  Thanks for any ideas or suggestions.
>
> Randall.
>
> ___
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] "Pickling" an in-memory SQLite database.

2019-01-31 Thread Randall Smith
Hi, guys.

I have an application that allows me to embed a (potentially large) block of 
data into its application file at close, and read the block back on open.  It 
would be convenient and attractive for me, for a plugin I am writing for this 
application, to be able to use an in-memory SQLite database, and then squirrel 
the DB away with everything else in the application file.  That way, everything 
would be stored under one roof, so to speak.

My question:  Is there a good way to "pickle" a SQLite database into a block of 
bytes for storage, and then "unpickle" it later for use?  My fantasy is that 
this could all be done in memory so the file system does not have to become 
involved.

I feel like I am missing something obvious here, but can't quite come up with 
it.  Thanks for any ideas or suggestions.

Randall.

___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] How to do I get an 'AND' condition to work in an SQLite query?

2019-01-31 Thread Simon Slavin
On 31 Jan 2019, at 6:21pm, Scott  wrote:

> Figured it out! I had set the column Deleted to "CHAR" but all the fields 
> without 'X' were null. If I replaced null with a valid character it worked.
> Thanks for your time.

Ah, JOINing on NULL.  Well done.

For future reference, SQLite doesn't have a CHAR type.  For clarity you might 
want to use TEXT instead.  SQLite does assume TEXT when you specify CHAR, but 
you might be depending on a specifically CHAR behaviour, like truncation to one 
character, and SQLite will ignore it.

Well done for solving your problem.  The magic of posting.

Simon.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Displaying hierarchical structure

2019-01-31 Thread Jean-Luc Hainaut

On 31/01/2019 17:59, Bart Smissaert wrote:

Thanks, will try that.


order by PATH

So, where is this path coming from?


Simple, from a discrepancy between the script I have tested and the 
contents of this mail!

Here is the complete (tested) script:

create table CLOSURE(PARENT_ID integer,ID integer,PATH text,DIST integer);

create trigger CLOSURE_INS after insert on CLOSURE
for each row
begin
  insert into CLOSURE
  select new.PARENT_ID,ID,new.PATH||'/'||cast(ID as char),new.DIST+1 
from FOLDERS

  where  PARENT_ID = new.ID; end;

insert into CLOSURE select ID,ID,'1',0 from FOLDERS where ID = 1;

select *,substr('  ',1,2*DIST)||cast(ID as char) as Display from 
CLOSURE order by PATH;


+---++---+--+-+
| PARENT_ID | ID | PATH  | DIST | Display |
+---++---+--+-+
| 1 | 1  | 1 | 0| 1   |
| 1 | 2  | 1/2   | 1|   2 |
| 1 | 5  | 1/2/5 | 2| 5   |
| 1 | 6  | 1/2/6 | 2| 6   |
| 1 | 3  | 1/3   | 1|   3 |
| 1 | 4  | 1/4   | 1|   4 |
+---++---+--+-+

JL

___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] How to do I get an 'AND' condition to work in an SQLite query?

2019-01-31 Thread Scott
Figured it out! I had set the column Deleted to "CHAR" but all the fields 
without 'X' were null. If I replaced null with a valid character it worked.
Thanks for your time.
Scott ValleryEcclesiastes 4:9-10 

On Thursday, January 31, 2019, 12:46:34 PM EST, Scott 
 wrote:  
 
 I can return results successfully from the t.Topic and n.Deleted columns 
separately, but when I try to use AND I receive no results. I'm not sure what I 
may be doing wrong. This is my first exhaustive work with a database project, 
so I've had to learn some syntax along the way, but has me stumped.
SELECT n.NoteID, s.SourceType, s.Title, c.Summary FROM Comment as c
LEFT JOIN Notes as n ON n.CommentID = c.CommentID

LEFT JOIN Source as s ON n.SourceID = s.SourceID

LEFT JOIN Topic as t ON n.TopicID = t.TopicID

WHERE (t.Topic = 'Manuscript Copies') AND (n.Deleted <> 'X')



I've tried and even with INNER JOIN:
(WHERE t.Topic = 'Manuscript Copies') AND n.Deleted <> 'X')WHERE (t.Topic = 
'Manuscript Copies') AND (n.Deleted <> 'X')
WHERE t.Topic = 'Manuscript Copies' AND n.Deleted <> 'X'
Thanks,
Scott ValleryEcclesiastes 4:9-10  
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] How to do I get an 'AND' condition to work in an SQLite query?

2019-01-31 Thread Simon Slavin
On 31 Jan 2019, at 5:46pm, Scott  wrote:

> I can return results successfully from the t.Topic and n.Deleted columns 
> separately, but when I try to use AND I receive no results.

There was an optimization bug that looked like your example in some previous 
version of SQLite.  Are you running an up-to-date version of SQLite ?

Are you doing this in your own code or in the SQLite CLI tool ?  If possible, 
please test in the CLI tool.

Please execute "PRAGMA schema.integrity_check" just in case your database is 
corrupt.

Try removing everything that doesn't cause the problem.  So remove the JOIN to 
the Source table.

Swap the order of the conditions around the "AND".

Swap the order of the JOIN clauses.

Some combination of the above should tell you more about the problem.

Simon.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] How to do I get an 'AND' condition to work in an SQLite query?

2019-01-31 Thread Scott
I can return results successfully from the t.Topic and n.Deleted columns 
separately, but when I try to use AND I receive no results. I'm not sure what I 
may be doing wrong. This is my first exhaustive work with a database project, 
so I've had to learn some syntax along the way, but has me stumped.
SELECT n.NoteID, s.SourceType, s.Title, c.Summary FROM Comment as c
LEFT JOIN Notes as n ON n.CommentID = c.CommentID

LEFT JOIN Source as s ON n.SourceID = s.SourceID

LEFT JOIN Topic as t ON n.TopicID = t.TopicID

WHERE (t.Topic = 'Manuscript Copies') AND (n.Deleted <> 'X')



I've tried and even with INNER JOIN:
(WHERE t.Topic = 'Manuscript Copies') AND n.Deleted <> 'X')WHERE (t.Topic = 
'Manuscript Copies') AND (n.Deleted <> 'X')
WHERE t.Topic = 'Manuscript Copies' AND n.Deleted <> 'X'
Thanks,
Scott ValleryEcclesiastes 4:9-10
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Displaying hierarchical structure

2019-01-31 Thread Bart Smissaert
Thanks, will try that.

> order by PATH
So, where is this path coming from?

RBS

On Thu, Jan 31, 2019 at 4:08 PM Jean-Luc Hainaut 
wrote:

> Recursive CTEs are the most obvious technique to solve this kind of
> problems.
> However, a less known technique can do the job: recursive triggers.
> Here is how the closure of FOLDERS can be computed. It will be stored in
> table CLOSURE:
>
>  create table CLOSURE(PARENT_ID integer, ID integer, DIST integer);
>
> A trigger adds the children rows of each row that has been inserted into
> this table:
>
>  create trigger CLOSURE_INS after insert on CLOSURE
>  for each row
>  begin
>insert into CLOSURE
>select new.PARENT_ID,ID,new.DIST+1 from FOLDERS
>where  PARENT_ID = new.ID;
>  end;
>
> To compute the closure, we just insert the root node:
>
>  insert into CLOSURE select ID,ID,0 from FOLDERS where ID = 1;
>
> or all the nodes:
>
>  insert into CLOSURE select ID,ID,0 from FOLDERS;
>
> To get the strict closure, we discard the initial rows (DIST = 0). And
> to display the node hierarchy:
>
>  select *,substr('  ',1,2*DIST)||cast(ID as char) as Display
>  from CLOSURE order by PATH;
>
> +---++--+-+
> | PARENT_ID | ID | DIST | Display |
> +---++--+-+
> | 1 | 1  | 0| 1   |
> | 1 | 2  | 1|   2 |
> | 1 | 5  | 2| 5   |
> | 1 | 6  | 2| 6   |
> | 1 | 3  | 1|   3 |
> | 1 | 4  | 1|   4 |
> +---++--+-+
>
> The path of each folder is computed in the same way.
>
> J-L Hainaut
>
> > Working on an Android app and part of that is storing SQL in a virtual
> > folder system in SQLite. For this I want to use a so-called closure table
> > as explained nicely here:
> >
> > http://technobytz.com/closure_table_store_hierarchical_data.html
> >
> > I have a table holder the folder details:
> >
> > ID PARENT_ID Folder
> >
> > -
> > 1  0   Folder1
> > 2  1   Folder2
> > 3  1   Folder3
> > 4  1   Folder4
> > 5  2   Folder5
> > 6  2   Folder6
> >
> >
> > And then the closure table:
> >
> > PARENT_ID CHILD_ID DEPTH
> >
> > ---
> > 1   10
> > 2   20
> > 3   30
> > 4   40
> > 5   50
> > 6   60
> > 1   21
> > 1   31
> > 1   41
> > 2   51
> > 1   52
> > 2   61
> > 1   62
> >
> > What should the SQL be to display the folders like this:
> >
> > FolderPARENT_ID
> > Folder1   0
> > Folder2   1
> >  Folder5   2
> >  Folder6   2
> > Folder3   1
> > Folder4   1
> >
> >
> > RBS
> > ___
> > sqlite-users mailing list
> > sqlite-users@mailinglists.sqlite.org
> > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
> ___
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Displaying hierarchical structure

2019-01-31 Thread Jean-Luc Hainaut
Recursive CTEs are the most obvious technique to solve this kind of 
problems.

However, a less known technique can do the job: recursive triggers.
Here is how the closure of FOLDERS can be computed. It will be stored in 
table CLOSURE:


create table CLOSURE(PARENT_ID integer, ID integer, DIST integer);

A trigger adds the children rows of each row that has been inserted into 
this table:


create trigger CLOSURE_INS after insert on CLOSURE
for each row
begin
  insert into CLOSURE
  select new.PARENT_ID,ID,new.DIST+1 from FOLDERS
  where  PARENT_ID = new.ID;
end;

To compute the closure, we just insert the root node:

insert into CLOSURE select ID,ID,0 from FOLDERS where ID = 1;

or all the nodes:

insert into CLOSURE select ID,ID,0 from FOLDERS;

To get the strict closure, we discard the initial rows (DIST = 0). And 
to display the node hierarchy:


select *,substr('  ',1,2*DIST)||cast(ID as char) as Display
from CLOSURE order by PATH;

+---++--+-+
| PARENT_ID | ID | DIST | Display |
+---++--+-+
| 1 | 1  | 0| 1   |
| 1 | 2  | 1|   2 |
| 1 | 5  | 2| 5   |
| 1 | 6  | 2| 6   |
| 1 | 3  | 1|   3 |
| 1 | 4  | 1|   4 |
+---++--+-+

The path of each folder is computed in the same way.

J-L Hainaut


Working on an Android app and part of that is storing SQL in a virtual
folder system in SQLite. For this I want to use a so-called closure table
as explained nicely here:

http://technobytz.com/closure_table_store_hierarchical_data.html

I have a table holder the folder details:

ID PARENT_ID Folder

-
1  0   Folder1
2  1   Folder2
3  1   Folder3
4  1   Folder4
5  2   Folder5
6  2   Folder6


And then the closure table:

PARENT_ID CHILD_ID DEPTH

---
1   10
2   20
3   30
4   40
5   50
6   60
1   21
1   31
1   41
2   51
1   52
2   61
1   62

What should the SQL be to display the folders like this:

FolderPARENT_ID
Folder1   0
Folder2   1
 Folder5   2
 Folder6   2
Folder3   1
Folder4   1


RBS
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Claimed vulnerability in SQLite: Info or Intox?

2019-01-31 Thread Digital Dog
On Mon, Jan 28, 2019 at 9:26 AM Vladimir Barbu <
vladimir.ba...@schneider-electric-dms.com> wrote:

> This vulnerability has been addressed in SQLite 3.26.0. When could we
> expect new version (official) of System.Data.SQLite which uses 3.26.0?
>

That would also make it much easier to use new features from .NET, such as
window functions and *a lot* of bugfixes since 3.24.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Displaying hierarchical structure

2019-01-31 Thread Keith Medcalf

Using the transitive_closure virtual table extension (closure.c) on your 
original question (my sqlite3 has everything built-in already, so no need to 
load the extension):

Note though that the AVL tree generated by the closure extension is generated 
on the fly upon request and does not have a materialized backing store.

create table folders
(
   idinteger primary key,
   parent_id integer references folders,
   name  text not null collate nocase,
   check (not (parent_id is null and id != 1))
);
create index foldersparentid on folders (parent_id);

create virtual table Closure using transitive_closure;

create view folders_closure
as select folders.id as PARENT_ID,
  Closure.id as CHILD_ID,
  Closure.depth as DEPTH
  from folders, Closure
 where Closure.root == folders.id
   and Closure.tablename = 'folders'
   and Closure.idcolumn = 'id'
   and Closure.parentcolumn = 'parent_id';

insert into folders values (1, null, 'Folder1'),
   (2, 1, 'Folder2'),
   (3, 1, 'Folder3'),
   (4, 1, 'Folder4'),
   (5, 2, 'Folder5'),
   (6, 2, 'Folder6');
.head on
.mode column
.width 30 9 38

-- depth first

with foo (id, parent_id, name, level, path)
  as (select folders.*, 0, folders.name
from folders
   where parent_id is null
   union all
  select folders.*, level + 1, foo.path || '\' || folders.name
from foo, folders
   where folders.parent_id = foo.id
order by 4
 )
select substr('', 1, (level - 1) * 4) || name as Folder,
   coalesce(parent_id, 0) as PARENT_ID,
   path as FullPath
  from foo;


-- breadth first

with foo (id, parent_id, name, level, path)
  as (select folders.*, 0, folders.name
from folders
   where parent_id is null
   union all
  select folders.*, level + 1, foo.path || '\' || folders.name
from foo, folders
   where folders.parent_id = foo.id
order by 4 desc
 )
select substr('', 1, (level - 1) * 4) || name as Folder,
   coalesce(parent_id, 0) as PARENT_ID,
   path as FullPath
  from foo;

-- folders_closure

.width 9 9 9

select *
  from folders_closure;



SQLite version 3.27.0 2019-01-31 02:42:47
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> create table folders
   ...> (
   ...>idinteger primary key,
   ...>parent_id integer references folders,
   ...>name  text not null collate nocase,
   ...>check (not (parent_id is null and id != 1))
   ...> );
sqlite> create index foldersparentid on folders (parent_id);
sqlite>
sqlite> create virtual table Closure using transitive_closure;
sqlite>
sqlite> create view folders_closure
   ...> as select folders.id as PARENT_ID,
   ...>   Closure.id as CHILD_ID,
   ...>   Closure.depth as DEPTH
   ...>   from folders, Closure
   ...>  where Closure.root == folders.id
   ...>and Closure.tablename = 'folders'
   ...>and Closure.idcolumn = 'id'
   ...>and Closure.parentcolumn = 'parent_id';
sqlite>
sqlite> insert into folders values (1, null, 'Folder1'),
   ...>(2, 1, 'Folder2'),
   ...>(3, 1, 'Folder3'),
   ...>(4, 1, 'Folder4'),
   ...>(5, 2, 'Folder5'),
   ...>(6, 2, 'Folder6');
sqlite> .head on
sqlite> .mode column
sqlite> .width 30 9 38
sqlite>
sqlite> -- depth first
sqlite>
sqlite> with foo (id, parent_id, name, level, path)
   ...>   as (select folders.*, 0, folders.name
   ...> from folders
   ...>where parent_id is null
   ...>union all
   ...>   select folders.*, level + 1, foo.path || '\' || folders.name
   ...> from foo, folders
   ...>where folders.parent_id = foo.id
   ...> order by 4
   ...>  )
   ...> select substr('', 1, (level - 1) * 4) || name as 
Folder,
   ...>coalesce(parent_id, 0) as PARENT_ID,
   ...>path as FullPath
   ...>   from foo;
Folder  PARENT_ID  FullPath
--  -  
--
Folder1 0  Folder1
Folder2 1  Folder1\Folder2
Folder3 1  Folder1\Folder3
Folder4 1  Folder1\Folder4
Folder5 2  Folder1\Folder2\Folder5
Folder6 2  Folder1\Folder2\Folder6
sqlite>
sqlite>
sqlite> -- breadth first
sqlite>
sqlite> with foo (id, parent_id, name, level, path)
   ...>   as (select folders.*, 0, folders.name
   ...> 

Re: [sqlite] Displaying hierarchical structure

2019-01-31 Thread Bart Smissaert
Thanks, second link regarding the extension looks interesting.

RBS

On Thu, Jan 31, 2019 at 8:32 AM Peter Johnson 
wrote:

> some relevant links:
>
> http://dwhoman.com/blog/sql-transitive-closure.html
>
>
> http://charlesleifer.com/blog/querying-tree-structures-in-sqlite-using-python-and-the-transitive-closure-extension/
>
> On Wed, 30 Jan 2019, 4:52 AM Bart Smissaert  wrote:
>
> > Working on an Android app and part of that is storing SQL in a virtual
> > folder system in SQLite. For this I want to use a so-called closure table
> > as explained nicely here:
> >
> > http://technobytz.com/closure_table_store_hierarchical_data.html
> >
> > I have a table holder the folder details:
> >
> > ID PARENT_ID Folder
> >
> > -
> > 1  0   Folder1
> > 2  1   Folder2
> > 3  1   Folder3
> > 4  1   Folder4
> > 5  2   Folder5
> > 6  2   Folder6
> >
> >
> > And then the closure table:
> >
> > PARENT_ID CHILD_ID DEPTH
> >
> > ---
> > 1   10
> > 2   20
> > 3   30
> > 4   40
> > 5   50
> > 6   60
> > 1   21
> > 1   31
> > 1   41
> > 2   51
> > 1   52
> > 2   61
> > 1   62
> >
> > What should the SQL be to display the folders like this:
> >
> > FolderPARENT_ID
> > Folder1   0
> > Folder2   1
> > Folder5   2
> > Folder6   2
> > Folder3   1
> > Folder4   1
> >
> >
> > RBS
> > ___
> > sqlite-users mailing list
> > sqlite-users@mailinglists.sqlite.org
> > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> >
> ___
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Displaying hierarchical structure

2019-01-31 Thread Peter Johnson
some relevant links:

http://dwhoman.com/blog/sql-transitive-closure.html

http://charlesleifer.com/blog/querying-tree-structures-in-sqlite-using-python-and-the-transitive-closure-extension/

On Wed, 30 Jan 2019, 4:52 AM Bart Smissaert  Working on an Android app and part of that is storing SQL in a virtual
> folder system in SQLite. For this I want to use a so-called closure table
> as explained nicely here:
>
> http://technobytz.com/closure_table_store_hierarchical_data.html
>
> I have a table holder the folder details:
>
> ID PARENT_ID Folder
>
> -
> 1  0   Folder1
> 2  1   Folder2
> 3  1   Folder3
> 4  1   Folder4
> 5  2   Folder5
> 6  2   Folder6
>
>
> And then the closure table:
>
> PARENT_ID CHILD_ID DEPTH
>
> ---
> 1   10
> 2   20
> 3   30
> 4   40
> 5   50
> 6   60
> 1   21
> 1   31
> 1   41
> 2   51
> 1   52
> 2   61
> 1   62
>
> What should the SQL be to display the folders like this:
>
> FolderPARENT_ID
> Folder1   0
> Folder2   1
> Folder5   2
> Folder6   2
> Folder3   1
> Folder4   1
>
>
> RBS
> ___
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Displaying hierarchical structure

2019-01-31 Thread Bart Smissaert
This looks a nice and simple way to display the tree in the right order
without recursive SQL:

https://coderwall.com/p/lixing/closure-tables-for-browsing-trees-in-sql

Will do some testing on large numbers to see how the 2 methods compare
speed-wise.

RBS

On Tue, Jan 29, 2019 at 8:33 PM Keith Medcalf  wrote:

>
> See https://sqlite.org/lang_with.html
>
> which includes how to traverse the recursive tree in either depth-first or
> breadth-first order.
>
> Why do you need the closure table at all?
>
>
> create table folders
> (
>idinteger primary key,
>parent_id integer references folders,
>name  text not null collate nocase,
>check (not (parent_id is null and id != 1))
> );
>
> insert into folders values (1, null, 'Folder1'),
>(2, 1, 'Folder2'),
>(3, 1, 'Folder3'),
>(4, 1, 'Folder4'),
>(5, 2, 'Folder5'),
>(6, 2, 'Folder6');
> .head on
> .mode column
> .width 30 9 38
>
> -- depth first
>
> with foo (id, parent_id, name, level, path)
>   as (select folders.*, 0, folders.name
> from folders
>where parent_id is null
>union all
>   select folders.*, level + 1, foo.path || '\' || folders.name
> from foo, folders
>where folders.parent_id = foo.id
> order by 4
>  )
> select substr('', 1, (level - 1) * 4) || name as
> Folder,
>coalesce(parent_id, 0) as PARENT_ID,
>path as FullPath
>   from foo;
>
>
> -- breadth first
>
> with foo (id, parent_id, name, level, path)
>   as (select folders.*, 0, folders.name
> from folders
>where parent_id is null
>union all
>   select folders.*, level + 1, foo.path || '\' || folders.name
> from foo, folders
>where folders.parent_id = foo.id
> order by 4 desc
>  )
> select substr('', 1, (level - 1) * 4) || name as
> Folder,
>coalesce(parent_id, 0) as PARENT_ID,
>path as FullPath
>   from foo;
>
>
>
> SQLite version 3.27.0 2019-01-28 00:42:06
> Enter ".help" for usage hints.
> Connected to a transient in-memory database.
> Use ".open FILENAME" to reopen on a persistent database.
> sqlite> create table folders
>...> (
>...>idinteger primary key,
>...>parent_id integer references folders,
>...>name  text not null collate nocase,
>...>check (not (parent_id is null and id != 1))
>...> );
> sqlite>
> sqlite> insert into folders values (1, null, 'Folder1'),
>...>(2, 1, 'Folder2'),
>...>(3, 1, 'Folder3'),
>...>(4, 1, 'Folder4'),
>...>(5, 2, 'Folder5'),
>...>(6, 2, 'Folder6');
> sqlite> .head on
> sqlite> .mode column
> sqlite> .width 30 9 38
> sqlite>
> sqlite> -- depth first
> sqlite>
> sqlite> with foo (id, parent_id, name, level, path)
>...>   as (select folders.*, 0, folders.name
>...> from folders
>...>where parent_id is null
>...>union all
>...>   select folders.*, level + 1, foo.path || '\' ||
> folders.name
>...> from foo, folders
>...>where folders.parent_id = foo.id
>...> order by 4
>...>  )
>...> select substr('', 1, (level - 1) * 4) || name
> as Folder,
>...>coalesce(parent_id, 0) as PARENT_ID,
>...>path as FullPath
>...>   from foo;
> Folder  PARENT_ID  FullPath
> --  -
> --
> Folder1 0  Folder1
> Folder2 1  Folder1\Folder2
> Folder3 1  Folder1\Folder3
> Folder4 1  Folder1\Folder4
> Folder5 2  Folder1\Folder2\Folder5
> Folder6 2  Folder1\Folder2\Folder6
> sqlite>
> sqlite>
> sqlite> -- breadth first
> sqlite>
> sqlite> with foo (id, parent_id, name, level, path)
>...>   as (select folders.*, 0, folders.name
>...> from folders
>...>where parent_id is null
>...>union all
>...>   select folders.*, level + 1, foo.path || '\' ||
> folders.name
>...> from foo, folders
>...>where folders.parent_id = foo.id
>...> order by 4 desc
>...>  )
>...> select substr('', 1, (level - 1) * 4) || name
> as Folder,
>...>coalesce(parent_id, 0) as PARENT_ID,
>...>path as FullPath
>...>   from foo;
> Folder  PARENT_ID  FullPath
>