libsql 0.1.0-x64-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +60 -0
  3. data/HISTORY.md +6 -0
  4. data/LICENSE +31 -0
  5. data/Manifest.txt +96 -0
  6. data/README.md +59 -0
  7. data/Rakefile +28 -0
  8. data/TODO.md +57 -0
  9. data/examples/a.rb +9 -0
  10. data/examples/blob.rb +106 -0
  11. data/examples/define_aggregate.rb +75 -0
  12. data/examples/define_function.rb +104 -0
  13. data/examples/fts5.rb +152 -0
  14. data/examples/gem-db.rb +94 -0
  15. data/examples/schema-info.rb +34 -0
  16. data/ext/libsql/c/extconf.rb +86 -0
  17. data/ext/libsql/c/gen_constants.rb +353 -0
  18. data/ext/libsql/c/libsql_blob.c +240 -0
  19. data/ext/libsql/c/libsql_constants.c +1518 -0
  20. data/ext/libsql/c/libsql_database.c +1188 -0
  21. data/ext/libsql/c/libsql_ext.c +383 -0
  22. data/ext/libsql/c/libsql_ext.h +149 -0
  23. data/ext/libsql/c/libsql_statement.c +649 -0
  24. data/ext/libsql/c/notes.txt +134 -0
  25. data/ext/libsql/c/sqlite3.c +247030 -0
  26. data/ext/libsql/c/sqlite3.h +13436 -0
  27. data/lib/libsql/aggregate.rb +73 -0
  28. data/lib/libsql/blob.rb +186 -0
  29. data/lib/libsql/boolean.rb +42 -0
  30. data/lib/libsql/busy_timeout.rb +47 -0
  31. data/lib/libsql/column.rb +99 -0
  32. data/lib/libsql/csv_table_importer.rb +75 -0
  33. data/lib/libsql/database.rb +933 -0
  34. data/lib/libsql/function.rb +61 -0
  35. data/lib/libsql/index.rb +43 -0
  36. data/lib/libsql/libsql_ext.so +0 -0
  37. data/lib/libsql/memory_database.rb +15 -0
  38. data/lib/libsql/paths.rb +80 -0
  39. data/lib/libsql/profile_tap.rb +131 -0
  40. data/lib/libsql/progress_handler.rb +21 -0
  41. data/lib/libsql/schema.rb +225 -0
  42. data/lib/libsql/sqlite3/constants.rb +95 -0
  43. data/lib/libsql/sqlite3/database/function.rb +48 -0
  44. data/lib/libsql/sqlite3/database/status.rb +68 -0
  45. data/lib/libsql/sqlite3/libsql_version.rb +32 -0
  46. data/lib/libsql/sqlite3/status.rb +60 -0
  47. data/lib/libsql/sqlite3/version.rb +55 -0
  48. data/lib/libsql/sqlite3.rb +7 -0
  49. data/lib/libsql/statement.rb +421 -0
  50. data/lib/libsql/table.rb +91 -0
  51. data/lib/libsql/taps/console.rb +27 -0
  52. data/lib/libsql/taps/io.rb +74 -0
  53. data/lib/libsql/taps.rb +2 -0
  54. data/lib/libsql/trace_tap.rb +35 -0
  55. data/lib/libsql/type_map.rb +63 -0
  56. data/lib/libsql/type_maps/default_map.rb +166 -0
  57. data/lib/libsql/type_maps/storage_map.rb +38 -0
  58. data/lib/libsql/type_maps/text_map.rb +21 -0
  59. data/lib/libsql/version.rb +8 -0
  60. data/lib/libsql/view.rb +26 -0
  61. data/lib/libsql-ruby.rb +1 -0
  62. data/lib/libsql.rb +51 -0
  63. data/spec/aggregate_spec.rb +158 -0
  64. data/spec/blob_spec.rb +78 -0
  65. data/spec/boolean_spec.rb +24 -0
  66. data/spec/busy_handler.rb +157 -0
  67. data/spec/data/iso-3166-country.txt +242 -0
  68. data/spec/data/iso-3166-schema.sql +22 -0
  69. data/spec/data/iso-3166-subcountry.txt +3995 -0
  70. data/spec/data/make-iso-db.sh +12 -0
  71. data/spec/database_spec.rb +505 -0
  72. data/spec/default_map_spec.rb +92 -0
  73. data/spec/function_spec.rb +78 -0
  74. data/spec/integeration_spec.rb +97 -0
  75. data/spec/iso_3166_database.rb +58 -0
  76. data/spec/json_spec.rb +24 -0
  77. data/spec/libsql_spec.rb +4 -0
  78. data/spec/paths_spec.rb +28 -0
  79. data/spec/progress_handler_spec.rb +91 -0
  80. data/spec/rtree_spec.rb +66 -0
  81. data/spec/schema_spec.rb +131 -0
  82. data/spec/spec_helper.rb +48 -0
  83. data/spec/sqlite3/constants_spec.rb +108 -0
  84. data/spec/sqlite3/database_status_spec.rb +36 -0
  85. data/spec/sqlite3/libsql_version_spec.rb +16 -0
  86. data/spec/sqlite3/status_spec.rb +22 -0
  87. data/spec/sqlite3/version_spec.rb +28 -0
  88. data/spec/sqlite3_spec.rb +53 -0
  89. data/spec/statement_spec.rb +168 -0
  90. data/spec/storage_map_spec.rb +38 -0
  91. data/spec/tap_spec.rb +57 -0
  92. data/spec/text_map_spec.rb +20 -0
  93. data/spec/type_map_spec.rb +14 -0
  94. data/spec/version_spec.rb +8 -0
  95. data/tasks/custom.rake +134 -0
  96. data/tasks/default.rake +257 -0
  97. data/tasks/extension.rake +29 -0
  98. data/tasks/this.rb +208 -0
  99. metadata +328 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 48d721e98569f960a2d4deabb3793ec32343932bab2bb75bac0c3d8c926a9374
4
+ data.tar.gz: 05f2c03faa420acbd7811325d6c293a50d0980e1de59b655fa54b377e1bba85f
5
+ SHA512:
6
+ metadata.gz: b596afed29498975a4f19b2c9ccd910780595b98cdc5f5254569c85e10185a35fd6e95fc6599f1db4b044e13c7d43bdc956474b3d8e753e6d0258a64014fd3ce
7
+ data.tar.gz: 8bdd4d403a4ca0ab8327054b597c5bf8a97f30cc9137431f1e48002db8c1f7f581a9a261cbdecd9fa3c77cbafa5ba36e2c95dcb8a1d042bd5998be5a3f19fe68
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,60 @@
1
+ # Hi there!
2
+
3
+ I see you are interested in contributing. That is wonderful. I love
4
+ contributions.
5
+
6
+ I guarantee that there are bugs in this software. And I guarantee that there is
7
+ a feature you want that is not in here yet. As such, any and all bugs reports
8
+ are gratefully accepted, bugfixes even more so. Helping out with bugs is the
9
+ easiest way to contribute.
10
+
11
+
12
+ ## The Quick Version
13
+
14
+ * Have a [GitHub Account][].
15
+ * Search the [GitHub Issues][] and see if your issue already present. If so
16
+ add your comments, :thumbsup:, etc.
17
+ * Issue not there? Not a problem, open up a [new issue][].
18
+ * **Bug reports** please be as detailed as possible. Include:
19
+ * full ruby engine and version: `ruby -e 'puts RUBY_DESCRIPTION'`
20
+ * operating system and version
21
+ * version of libsql `ruby -rubygems -e "require 'libsql'; puts Libsql::VERSION"`
22
+ * as much detail about the bug as possible so I can replicate it. Feel free
23
+ to link in a [gist][]
24
+ * **New Feature**
25
+ * What the new feature should do.
26
+ * What benefit the new feature brings to the project.
27
+ * Fork the [repo][].
28
+ * Create a new branch for your issue: `git checkout -b issue/my-issue`
29
+ * Lovingly craft your contribution:
30
+ * `rake develop` to get started, or if you prefer bundler `rake develop:using_bundler && bundle`.
31
+ * `rake test` to run tests
32
+ * Make sure that `rake test` passes. It's important, I said it twice.
33
+ * Add yourself to the contributors section below.
34
+ * Submit your [pull request][].
35
+
36
+ ## Building Windows Binaries
37
+
38
+ This is done using https://github.com/rake-compiler/rake-compiler-dock
39
+
40
+ 1. have VirtualBox installed
41
+ 2. have Docker Machine installed (https://docs.docker.com/engine/installation/)
42
+ 3. `gem install rake-compiler-dock`
43
+ 4. `rake-compiler-dock` (this could take a while)
44
+ 5. `bundle`
45
+ 6. `rake cross native gem`
46
+
47
+ # Contributors
48
+
49
+ * [Jeremy Hinegardner](https://github.com/copiousfreetime)
50
+ * [Jos Backus](https://github.com/josb)
51
+ * [Alex Young](https://github.com/regularfry)
52
+ * [Michael Granger](https://github.com/ged)
53
+ * [Alex Young](https://github.com/bmalex)
54
+
55
+ [GitHub Account]: https://github.com/signup/free "GitHub Signup"
56
+ [GitHub Issues]: https://github.com/copiousfreetime/libsql-ruby/issues "libsql-ruby Issues"
57
+ [new issue]: https://github.com/copiousfreetime/libsql-ruby/issues/new "New libsql-ruby Issue"
58
+ [gist]: https://gist.github.com/ "New Gist"
59
+ [repo]: https://github.com/copiousfreetime/libsql-ruby "libsql-ruby Repo"
60
+ [pull request]: https://help.github.com/articles/using-pull-requests "Using Pull Requests"
data/HISTORY.md ADDED
@@ -0,0 +1,6 @@
1
+ # Libsql Changelog
2
+
3
+ ## Version 0.1.0 - 2023-05-03
4
+ * Use the the [amalgalite](https://github.com/copiousfreetime/amalgalite) codebase to bootstrap libsql.
5
+ * Initial public release
6
+ * embedds [libSQL-v0.2.1](https://github.com/libsql/libsql/releases/tag/libsql-0.2.1)
data/LICENSE ADDED
@@ -0,0 +1,31 @@
1
+ BSD License - https://opensource.org/licenses/BSD-3-Clause
2
+
3
+ Copyright (c) 2023 Jeremy Hinegardner
4
+
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice,
11
+ this list of conditions and the following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above copyright notice,
14
+ this list of conditions and the following disclaimer in the documentation
15
+ and/or other materials provided with the distribution.
16
+
17
+ * Neither the name of Jeremy Hinegardner nor the names of its contributors
18
+ may be used to endorse or promote products derived from this software without
19
+ specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Manifest.txt ADDED
@@ -0,0 +1,96 @@
1
+ CONTRIBUTING.md
2
+ HISTORY.md
3
+ LICENSE
4
+ Manifest.txt
5
+ README.md
6
+ Rakefile
7
+ TODO.md
8
+ examples/a.rb
9
+ examples/blob.rb
10
+ examples/define_aggregate.rb
11
+ examples/define_function.rb
12
+ examples/fts5.rb
13
+ examples/gem-db.rb
14
+ examples/schema-info.rb
15
+ ext/libsql/c/extconf.rb
16
+ ext/libsql/c/gen_constants.rb
17
+ ext/libsql/c/libsql_blob.c
18
+ ext/libsql/c/libsql_constants.c
19
+ ext/libsql/c/libsql_database.c
20
+ ext/libsql/c/libsql_ext.c
21
+ ext/libsql/c/libsql_ext.h
22
+ ext/libsql/c/libsql_statement.c
23
+ ext/libsql/c/notes.txt
24
+ ext/libsql/c/sqlite3.c
25
+ ext/libsql/c/sqlite3.h
26
+ lib/libsql-ruby.rb
27
+ lib/libsql.rb
28
+ lib/libsql/aggregate.rb
29
+ lib/libsql/blob.rb
30
+ lib/libsql/boolean.rb
31
+ lib/libsql/busy_timeout.rb
32
+ lib/libsql/column.rb
33
+ lib/libsql/csv_table_importer.rb
34
+ lib/libsql/database.rb
35
+ lib/libsql/function.rb
36
+ lib/libsql/index.rb
37
+ lib/libsql/memory_database.rb
38
+ lib/libsql/paths.rb
39
+ lib/libsql/profile_tap.rb
40
+ lib/libsql/progress_handler.rb
41
+ lib/libsql/schema.rb
42
+ lib/libsql/sqlite3.rb
43
+ lib/libsql/sqlite3/constants.rb
44
+ lib/libsql/sqlite3/database/function.rb
45
+ lib/libsql/sqlite3/database/status.rb
46
+ lib/libsql/sqlite3/libsql_version.rb
47
+ lib/libsql/sqlite3/status.rb
48
+ lib/libsql/sqlite3/version.rb
49
+ lib/libsql/statement.rb
50
+ lib/libsql/table.rb
51
+ lib/libsql/taps.rb
52
+ lib/libsql/taps/console.rb
53
+ lib/libsql/taps/io.rb
54
+ lib/libsql/trace_tap.rb
55
+ lib/libsql/type_map.rb
56
+ lib/libsql/type_maps/default_map.rb
57
+ lib/libsql/type_maps/storage_map.rb
58
+ lib/libsql/type_maps/text_map.rb
59
+ lib/libsql/version.rb
60
+ lib/libsql/view.rb
61
+ spec/aggregate_spec.rb
62
+ spec/blob_spec.rb
63
+ spec/boolean_spec.rb
64
+ spec/busy_handler.rb
65
+ spec/data/iso-3166-country.txt
66
+ spec/data/iso-3166-schema.sql
67
+ spec/data/iso-3166-subcountry.txt
68
+ spec/data/make-iso-db.sh
69
+ spec/database_spec.rb
70
+ spec/default_map_spec.rb
71
+ spec/function_spec.rb
72
+ spec/integeration_spec.rb
73
+ spec/iso_3166_database.rb
74
+ spec/json_spec.rb
75
+ spec/libsql_spec.rb
76
+ spec/paths_spec.rb
77
+ spec/progress_handler_spec.rb
78
+ spec/rtree_spec.rb
79
+ spec/schema_spec.rb
80
+ spec/spec_helper.rb
81
+ spec/sqlite3/constants_spec.rb
82
+ spec/sqlite3/database_status_spec.rb
83
+ spec/sqlite3/libsql_version_spec.rb
84
+ spec/sqlite3/status_spec.rb
85
+ spec/sqlite3/version_spec.rb
86
+ spec/sqlite3_spec.rb
87
+ spec/statement_spec.rb
88
+ spec/storage_map_spec.rb
89
+ spec/tap_spec.rb
90
+ spec/text_map_spec.rb
91
+ spec/type_map_spec.rb
92
+ spec/version_spec.rb
93
+ tasks/custom.rake
94
+ tasks/default.rake
95
+ tasks/extension.rake
96
+ tasks/this.rb
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ ## libsql
2
+
3
+ [![Build Status](https://copiousfreetime.semaphoreci.com/badges/libsql-ruby/branches/main.svg)](https://copiousfreetime.semaphoreci.com/projects/libsql-ruby)
4
+
5
+ * [Homepage](http://github.com/copiousfreetime/libsql-ruby)
6
+ * `git clone git://github.com/copiousfreetime/libsql-ruby.git`
7
+ * [Github](http://github.com/copiousfreetime/libsql-ruby/)
8
+ * [Bug Tracking](http://github.com/copiousfreetime/libsql-ruby/issues)
9
+
10
+ ## INSTALL
11
+
12
+ * `gem install libsql`
13
+ * `bundle add libsql`
14
+
15
+ ## DESCRIPTION
16
+
17
+ libsql embeds the libsql fork of the SQLite database engine as a ruby extension.
18
+ There is no need to install libsql separately.
19
+
20
+ Look in the examples/ directory to see
21
+
22
+ * general usage
23
+ * blob io
24
+ * schema information
25
+ * custom functions
26
+ * custom aggregates
27
+ * requiring ruby code from a database
28
+ * full text search
29
+
30
+ Also scroll through Libsql::Database for a quick example, and a general
31
+ overview of the API.
32
+
33
+ libsql adds in the following additional non-default SQLite extensions:
34
+
35
+ * [R*Tree index extension](http://sqlite.org/rtree.html)
36
+ * [Full Text Search](http://sqlite.org/fts5.html) - both fts3 and fts5
37
+ * [Geopoly Interface to R*Tree](https://www.sqlite.org/geopoly.html)
38
+ * [JSON Extension](https://www.sqlite.org/json1.html)
39
+
40
+ Other extensions are add that might not be usable/visible by users of the gem.
41
+ The full list of extensions added is in
42
+ [extconf.rb](ext/libsql/c/extconf.rb). And those may be cross referenced
43
+ against the [compile options from SQLite](https://www.sqlite.org/compile.html)
44
+
45
+ ## CREDITS
46
+
47
+ * This is a straight port of the [amalgalite](https://github.com/copiousfreetime/amalgalite) gem, also written by me.
48
+
49
+ ## CHANGES
50
+
51
+ Read the [HISTORY.md](HISTORY.md) file.
52
+
53
+ ## LICENSE
54
+
55
+ Copyright (c) 2023 Jeremy Hinegardner
56
+
57
+ All rights reserved.
58
+
59
+ See LICENSE and/or COPYING for details.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ # vim: syntax=ruby
2
+ load 'tasks/this.rb'
3
+
4
+ This.name = "libsql"
5
+ This.author = "Jeremy Hinegardner"
6
+ This.email = "jeremy@copiousfreetime.org"
7
+ This.homepage = "http://github.com/copiousfreetime/#{ This.name }-ruby"
8
+
9
+ This.ruby_gemspec do |spec|
10
+ spec.add_dependency( 'arrayfields', '~> 4.9' )
11
+
12
+ spec.add_development_dependency( 'debug', '~> 1.0' )
13
+ spec.add_development_dependency( 'rspec', '~> 3.12' )
14
+ spec.add_development_dependency( 'rspec_junit_formatter','~> 0.6' )
15
+ spec.add_development_dependency( 'rake', '~> 13.0' )
16
+ spec.add_development_dependency( 'rake-compiler', '~> 1.2' )
17
+ spec.add_development_dependency( 'rake-compiler-dock', '~> 1.3' )
18
+ spec.add_development_dependency( 'rdoc', '~> 6.5' )
19
+ spec.add_development_dependency( 'simplecov', '~> 0.21' )
20
+ spec.add_development_dependency( 'archive-zip', '~> 0.12' )
21
+
22
+ spec.extensions.concat This.extension_conf_files
23
+ spec.license = "BSD-3-Clause"
24
+ end
25
+
26
+ load 'tasks/default.rake'
27
+ load 'tasks/extension.rake'
28
+ load 'tasks/custom.rake'
data/TODO.md ADDED
@@ -0,0 +1,57 @@
1
+ # Future Release possibilties:
2
+ - rebuild statement constants
3
+ - look at all pragma statements
4
+
5
+ ## SQLite API:
6
+ - authorizers
7
+ - loading of extensions -- readfile / writefile
8
+ - utf-16 integration
9
+ - create_collation
10
+ - encryption key support
11
+ - expose sqlite3_strnicmp
12
+ - table name and column name in a type map?
13
+ - type conversion for manifest typing? how to allow it through?
14
+ - explicit pragma handler
15
+ - application_id pragma setter
16
+
17
+ ## Non backwards compatible changes:
18
+ - change the schema objects to be more consistent
19
+ - change taps to use to_proc protocol
20
+ - convert type dependency to just use 'call'
21
+ - integrate transaction and savepoint under the same api
22
+
23
+ ## SQLite Features:
24
+ - activate SQLITE_ENABLE_ICU extension
25
+ - activate SQLITE_ENABLE_LOCKING_STYLE
26
+ - activate SQLITE_ENABLE_UNLOCK_NOTIFY
27
+ - expose PRAGMA foreign_keys
28
+ - virtual file system
29
+ - full text search (FTS3)
30
+ - expose the sqlite mutex lib
31
+ - statement status ( sqlite3_stmt_status )
32
+ - db status ( sqlite3_db_status )
33
+ - library status ( sqlite3_status )
34
+ - sqlite3_index_info
35
+ - sqlite3_create_function has 4th parameter SQLITE_DETERMINISTIC
36
+ - sqlite3_rtree_query_callback()
37
+
38
+ ## Drivers:
39
+ - data mapper driver
40
+ - sequel driver optimization
41
+
42
+ ## Features:
43
+ - Think about moving from arrayfields to ordered hash?
44
+ - add to command line which directory to pack into a rubylibs table
45
+ - command line tool
46
+ - use ruby's ALLOC_N and hook into sqlite3_mem_methods
47
+
48
+ ## Functions to possibly expose:
49
+ - sqlite3_backup_remaining, sqlite3_backup_pagecount
50
+ - sqlite3_compileoption_used, sqlite3_compileoption_get
51
+ - sqlite3_config
52
+ - sqlite3_data_count - returns number of colums in the result set of a
53
+ prepared statement
54
+ - sqlite_sourceid, sqlite_source_id
55
+ - sqlite3_strnicmp
56
+ -
57
+
data/examples/a.rb ADDED
@@ -0,0 +1,9 @@
1
+ class A
2
+ def initialize
3
+ puts "Initialized A"
4
+ end
5
+
6
+ def a
7
+ puts "called a"
8
+ end
9
+ end
data/examples/blob.rb ADDED
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #
4
+ # A Libsql example showing how Blob's can be utilized
5
+ #
6
+ # We'll make a database with one table, that we store files in. We'll use the
7
+ # Blob incremental IO to store the files and retrieve them from the database
8
+ #
9
+ # This little program will store 1 or more files in the sqlite3 database when
10
+ # the 'store' action is given, and cat a file to stdout on 'retrieve'
11
+ #
12
+ # e.g.
13
+ #
14
+ # ruby blob.rb store a.rb b.rb c.rb # => stores a.rb b.rb and c.rb in the db
15
+ #
16
+ # ruby blob.rb retrieve a.rb # => dumps a.rb to stdout
17
+ #
18
+
19
+ require 'rubygems'
20
+ $: << "../lib"
21
+ $: << "../ext"
22
+ require 'libsql'
23
+ VALID_ACTIONS = %w[ list retrieve store ]
24
+ def usage
25
+ STDERR.puts "Usage: #{File.basename($0)} ( #{VALID_ACTIONS.join(' | ')} ) file(s)"
26
+ exit 1
27
+ end
28
+
29
+ #
30
+ # This does the basic command line parsing
31
+ #
32
+ usage if ARGV.size < 1
33
+ action = ARGV.shift
34
+ usage unless VALID_ACTIONS.include? action
35
+ file_list = ARGV
36
+
37
+ #
38
+ # create the database if it doesn't exist
39
+ #
40
+ db = ::Libsql::Database.new( "filestore.db" )
41
+ schema = db.schema
42
+ unless schema.tables['files']
43
+
44
+ schema = <<~SQL
45
+ CREATE TABLE files (
46
+ id integer primary key autoincrement,
47
+ filename text unique,
48
+ contents blob
49
+ )
50
+ SQL
51
+
52
+ db.execute(schema)
53
+ db.reload_schema!
54
+ end
55
+
56
+
57
+ case action
58
+ #
59
+ # list all the files that are stored in the database
60
+ #
61
+ when 'list'
62
+ db.execute("SELECT filename FROM files") do |row|
63
+ puts row['filename']
64
+ end
65
+
66
+ #
67
+ # if we are doing the store action, then loop over the files and store them in
68
+ # the database. This will use incremental IO to store the files directly from
69
+ # the file names.
70
+ #
71
+ # It is slightly strange in that you have to tell the Blob object what column
72
+ # it is going to, but that is necessary at this point to be able to hook
73
+ # automatically into the lower level incremental blob IO api.
74
+ #
75
+ # This also shows using the $var syntax for binding name sql values in a
76
+ # prepared statement.
77
+ #
78
+ when 'store'
79
+ usage if file_list.empty?
80
+
81
+ contents_column = db.schema.tables['files'].columns['contents']
82
+ db.transaction do |trans|
83
+ trans.prepare("INSERT INTO files (filename, contents) VALUES ($filename, $contents)") do |stmt|
84
+ file_list.each do |file_path|
85
+ contents = IO.read(file_path)
86
+ content_io = StringIO.new(contents)
87
+ stmt.execute("$filename" => file_path,
88
+ "$contents" => ::Libsql::Blob.new(io: content_io,
89
+ column: contents_column)
90
+ )
91
+ end
92
+ end
93
+ end
94
+
95
+ #
96
+ # dump the file that matches the right path to stdout. This also shows
97
+ # positional sql varible binding using the '?' syntax.
98
+ #
99
+ when 'retrieve'
100
+ usage if file_list.empty?
101
+ db.execute("SELECT id, filename, contents FROM files WHERE filename = ?", file_list.first) do |row|
102
+ STDERR.puts "Dumping #{row['filename']} to stdout"
103
+ row['contents'].write_to_io( STDOUT )
104
+ end
105
+ end
106
+ db.close
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ $: << "../lib"
5
+ $: << "../ext"
6
+ require 'libsql'
7
+
8
+ #--
9
+ # Create a database and a table to put some results from the functions in
10
+ #--
11
+ db = ::Libsql::Database.new( ":memory:" )
12
+ db.execute( "CREATE TABLE atest( words )" )
13
+
14
+ #------------------------------------------------------------------------------
15
+ # Create unique word count aggregate
16
+ #------------------------------------------------------------------------------
17
+ class UniqueWordCount < ::Libsql::Aggregate
18
+ attr_accessor :words
19
+
20
+ def initialize
21
+ @name = 'unique_word_count'
22
+ @arity = 1
23
+ @words = Hash.new { |h,k| h[k] = 0 }
24
+ end
25
+
26
+ def step( str )
27
+ str.split(/\W+/).each do |word|
28
+ words[ word.downcase ] += 1
29
+ end
30
+ return nil
31
+ end
32
+
33
+ def finalize
34
+ return words.size
35
+ end
36
+ end
37
+
38
+ db.define_aggregate( 'unique_word_count', UniqueWordCount )
39
+
40
+ #------------------------------------------------------------------------------
41
+ # Now we have a new aggregate function, lets insert some rows into the database
42
+ # and see what we can find.
43
+ #------------------------------------------------------------------------------
44
+ sql = "INSERT INTO atest( words ) VALUES( ? )"
45
+ verify = {}
46
+ db.prepare( sql ) do |stmt|
47
+ DATA.each do |words|
48
+ words.strip!
49
+ puts "Inserting #{words}"
50
+ stmt.execute( words )
51
+ words.split(/\W+/).each { |w| verify[w] = true }
52
+ end
53
+ end
54
+
55
+ #------------------------------------------------------------------------------
56
+ # And show the results
57
+ #------------------------------------------------------------------------------
58
+ puts
59
+ puts "Getting results..."
60
+ puts
61
+ all_rows = db.execute("SELECT unique_word_count( words ) AS uwc FROM atest")
62
+ puts "#{all_rows.first['uwc']} unique words found"
63
+ puts "#{verify.size} unique words to verify"
64
+
65
+ __END__
66
+ some random
67
+ words with
68
+ which
69
+ to play
70
+ and there should
71
+ be a couple of different
72
+ words that appear
73
+ more than once and
74
+ some that appear only
75
+ once
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ $: << "../lib"
5
+ $: << "../ext"
6
+ require 'libsql'
7
+
8
+ #--
9
+ # Create a database and a table to put some results from the functions in
10
+ #--
11
+ db = ::Libsql::Database.new( ":memory:" )
12
+ db.execute( "CREATE TABLE ftest( data, md5, sha1, sha2_bits, sha2)" )
13
+
14
+ #------------------------------------------------------------------------------
15
+ # Create an MD5 method using the block format of defining an sql fuction
16
+ #------------------------------------------------------------------------------
17
+ require 'digest/md5'
18
+ db.define_function( 'md5' ) do |x|
19
+ Digest::MD5.hexdigest( x.to_s )
20
+ end
21
+
22
+ #------------------------------------------------------------------------------
23
+ # Create a SHA1 method using the lambda format of defining an sql function
24
+ #------------------------------------------------------------------------------
25
+ require 'digest/sha1'
26
+ sha1 = lambda do |y|
27
+ Digest::SHA1.hexdigest( y.to_s )
28
+ end
29
+ db.define_function( "sha1", sha1 )
30
+
31
+ #------------------------------------------------------------------------------
32
+ # Create a SHA2 method using the class format for defining an sql function
33
+ # In this one we will allow any number of parameters, but we will only use the
34
+ # first two.
35
+ #------------------------------------------------------------------------------
36
+ require 'digest/sha2'
37
+ class SQLSha2
38
+ # track the number of invocations
39
+ attr_reader :call_count
40
+
41
+ def initialize
42
+ @call_count = 0
43
+ end
44
+
45
+ # the protocol that is used for sql function definition
46
+ def to_proc() self ; end
47
+
48
+ # say we take any number of parameters
49
+ def arity
50
+ -1
51
+ end
52
+
53
+ # The method that is called by SQLite, must be named 'call'
54
+ def call( *args )
55
+ text = args.shift.to_s
56
+ bitlength = (args.shift || 256).to_i
57
+ Digest::SHA2.new( bitlength ).hexdigest( text )
58
+ end
59
+ end
60
+ db.define_function('sha2', SQLSha2.new)
61
+
62
+
63
+ #------------------------------------------------------------------------------
64
+ # Now we have 3 new sql functions, each defined in one of the available methods
65
+ # to define sql functions in libsql. Lets insert some rows and look at the
66
+ # results
67
+ #------------------------------------------------------------------------------
68
+ possible_bits = [ 256, 384, 512 ]
69
+ sql = "INSERT INTO ftest( data, md5, sha1, sha2_bits, sha2 ) VALUES( @word , md5( @word ), sha1( @word ), @bits, sha2(@word,@bits) )"
70
+ db.prepare( sql ) do |stmt|
71
+ DATA.each do |word|
72
+ word.strip!
73
+ bits = possible_bits[ rand(3) ]
74
+ puts "Inserting #{word}, #{bits}"
75
+ stmt.execute( { '@word' => word, '@bits' => bits } )
76
+ end
77
+ end
78
+
79
+ #------------------------------------------------------------------------------
80
+ # And show the results
81
+ #------------------------------------------------------------------------------
82
+ puts
83
+ puts "Getting results..."
84
+ puts
85
+ columns = db.schema.tables['ftest'].columns.keys.sort
86
+ i = 0
87
+ db.execute("SELECT #{columns.join(',')} FROM ftest") do |row|
88
+ i += 1
89
+ puts "-----[ row #{i} ]-" + "-" * 42
90
+ columns.each do |col|
91
+ puts "#{col.ljust(10)} : #{row[col]}"
92
+ end
93
+ puts
94
+ end
95
+
96
+
97
+ __END__
98
+ some
99
+ random
100
+ words
101
+ with
102
+ which
103
+ to
104
+ play