Skip to content
Commits on Source (6)
......@@ -7,13 +7,16 @@
*.cmi
*.cmo
*.cma
*.cmt
*.cmti
*.cmxa
*.omc
.omakedb*
.*swp
*.s
gmon.out
/t_sqlexpr_sqlite
/test/t_sqlexpr_sqlite
oUnit-anon.cache
# generated by OASIS
/_build
/META
......@@ -23,7 +26,18 @@ gmon.out
/setup.ml
/setup.data
/setup.log
/src/META
/src/ppx/ppx_sqlexpr
/src/ppx/ppx.mllib
/src/sqlexpr.mllib
/src/syntax/sqlexpr_syntax.mllib
/sqlexpr.mllib
/sqlexpr.odocl
/sqlexpr_syntax.mllib
/tests/t_ppx_parse
/tests/t_ppx_sqlexpr
/tests/t_sqlexpr_sqlite
/toplevel
/ocaml-sqlexpr*
*.mldylib
.merlin
S src/
S src/syntax
S tests
B _build/src
B _build/src/syntax
B _build/tests
B +threads
PKG lwt
PKG lwt_ppx
PKG sqlite3
PKG unix
PKG csv
PKG thread
Mauricio Fernandez <mfp@acm.org>
Josh Allmann <joshua.allmann@gmail.com>
Simon Cruanes simon[dot]cruanes[dot]2007[at]m4x[dot]org
0.9.0 (2018-05-12)
=====
* migrate to jbuilder, move the PPX and Camlp4 extensions to separate packages
ppx_sqlexpr and pa_sqlexpr (Freyr).
* fix stack overflows when iterating/fold/selecting over many rows when
using Sqlexpr_concurrency.Id concurrency.
* multiple fixes to work with newer versions of Lwt and lwt_ppx.
Backwards compatibility is provided for the time being as follows:
* sqlexpr depends on ppx_sqlexpr, and a sqlexpr.ppx alias is provided
* if estring was installed (required if sqlexpr.syntax was being used),
sqlexpr.syntax will also be installed
* installing pa_sqlexpr will also install its estring dependency, and
cause a sqlexpr rebuild, so that sqlexpr.syntax is provided
These mean that it is still possible to (wherever it was before) compile e.g.
with
ocamlfind ocamlopt -package sqlexpr,sqlexpr.syntax -syntax camlp4o -c ...
but in the future the sqlexpr.syntax and sqlexpr.ppx aliases will be dropped,
so it is recommended to:
1) opam install ppx_sqlexpr and/or pa_sqlexpr explicitly
2) start using the ppx_sqlexpr instead of sqlexpr.ppx and pa_sqlexpr instead
of sqlexpr.syntax in your build system.
0.8.0
=====
* camlp4 syntax extension now optional (Josh Allmann)
0.7.0
=====
* PPX extension thanks to Josh Allmann
* more efficient row iteration/selection (in batches) in Sqlexpr_sqlite_lwt
* fix possible performance issue caused by the Event module
This is the INSTALL file for the ocaml-sqlexpr distribution.
This package uses OASIS to generate its build system. See section OASIS for
full information.
Dependencies
============
In order to compile this package, you will need:
* ocaml
* findlib
* estring
* csv
* batteries
* sqlite3
* lwt
* unix
Installing
==========
1. Uncompress source directory and got to the root of the package
2. Run 'ocaml setup.ml -configure'
3. Run 'ocaml setup.ml -build'
4. Run 'ocaml setup.ml -install'
Alternatively:
1. Uncompress source directory and got to the root of the package
2. Run './configure"
3. Run 'make"
4. Run 'make install"
Uninstalling
============
1. Go to the root of the package
2. Run 'ocaml setup.ml -uninstall'
OASIS
=====
OASIS is a software that helps to write setup.ml using a simple '_oasis'
configuration file. The generated setup only depends on standard OCaml
installation, no additional library is required.
# OASIS_START
# DO NOT EDIT (digest: 241cffd68e9612eb6fa812c6118b726f)
version = "0.5.5"
description = "SQLite database access."
requires = "csv batteries sqlite3 estring lwt lwt.syntax lwt.unix unix threads"
archive(byte) = "sqlexpr.cma"
archive(native) = "sqlexpr.cmxa"
exists_if = "sqlexpr.cma"
package "syntax" (
version = "0.5.5"
description = "Syntax extension for SQL statements/expressions"
requires = "camlp4 estring"
archive(syntax, preprocessor) = "sqlexpr_syntax.cma"
archive(syntax, toploop) = "sqlexpr_syntax.cma"
exists_if = "sqlexpr_syntax.cma"
)
# OASIS_STOP
version = "dev"
description = "Sqlexpr syntax extension"
requires = "camlp4 estring"
archive(syntax,preprocessor) = "pa_sql.cma"
archive(syntax, toploop) = "pa_sql.cma"
archive(syntax, preprocessor, native) = "pa_sql.cmxa"
archive(syntax, preprocessor, native, plugin) = "pa_sql.cmxs"
exists_if = "pa_sql.cma"
description = "Convenient, type-safe SQLite database access."
requires = "bigarray
bytes
csv
lwt
lwt.unix
result
sqlite3
threads
threads.posix
unix"
archive(byte) = "sqlexpr.cma"
archive(native) = "sqlexpr.cmxa"
plugin(byte) = "sqlexpr.cma"
plugin(native) = "sqlexpr.cmxs"
package "ppx" (
description = "Deprecated, use ppx_sqlexpr directly"
requires = "ppx_sqlexpr"
)
package "syntax" (
version = "dev"
description = "Sqlexpr syntax extension"
requires = "camlp4 estring"
archive(syntax,preprocessor) = "syntax/pa_sql_.cma"
archive(syntax, toploop) = "syntax/pa_sql_.cma"
archive(syntax, preprocessor, native) = "syntax/pa_sql_.cmxa"
archive(syntax, preprocessor, native, plugin) = "syntax/pa_sql_.cmxs"
exists_if = "syntax/pa_sql_.cma"
)
# OASIS_START
# DO NOT EDIT (digest: bc1e05bfc8b39b664f29dae8dbd3ebbb)
SETUP = ocaml setup.ml
build: setup.data
$(SETUP) -build $(BUILDFLAGS)
doc: setup.data build
$(SETUP) -doc $(DOCFLAGS)
test: setup.data build
$(SETUP) -test $(TESTFLAGS)
all:
$(SETUP) -all $(ALLFLAGS)
install: setup.data
$(SETUP) -install $(INSTALLFLAGS)
uninstall: setup.data
$(SETUP) -uninstall $(UNINSTALLFLAGS)
reinstall: setup.data
$(SETUP) -reinstall $(REINSTALLFLAGS)
clean:
$(SETUP) -clean $(CLEANFLAGS)
distclean:
$(SETUP) -distclean $(DISTCLEANFLAGS)
setup.data:
$(SETUP) -configure $(CONFIGUREFLAGS)
.PHONY: build doc test all install uninstall reinstall clean distclean configure
# OASIS_STOP
USE_OCAMLFIND = true
NATIVE_ENABLED = true
BYTE_ENABLED = true
USE_OCAMLFIND = true
OCAMLPACKS[] = csv batteries sqlite3 estring lwt lwt.unix lwt.syntax threads
OCAMLFINDFLAGS = -syntax camlp4o
OCAMLFLAGS += -thread
OCAMLPACKS[] =
csv
sqlite3
lwt
lwt_ppx
lwt.unix
threads
OCAMLOPTFLAGS =
OCAMLFLAGS = -thread -bin-annot -g -w +a-4-6-9-27..29-32..99 -warn-error -a
OCAMLDEP_MODULES_ENABLED = false
%.sig: %.ml %.cmo
$(OCAMLFIND) $(OCAMLC) -package $(concat \,, $(OCAMLPACKS)) \
$(OCAMLFIND) ocamlc -package $(concat \,, $(OCAMLPACKS)) \
$(OCAMLFINDFLAGS) \
$(mapprefix -I, $(OCAMLINCLUDES)) \
$(OCAMLFLAGS) $(OCAMLCFLAGS) -i $< > $@
section
NATIVE_ENABLED = false
OCAMLPACKS[] = estring camlp4.quotations
pa_sql.cmi pa_sql.cmo: pa_sql.ml
.SCANNER: scan-ocaml-%.ml: %.ml pa_sql.cmo
.SCANNER: scan-ocaml-%.mli: %.mli pa_sql.cmo
OCAMLFINDFLAGS += -syntax camlp4o -ppopt pa_sql.cmo
OCamlLibrary(sqlexpr, sqlexpr_concurrency sqlexpr_sqlite sqlexpr_sqlite_lwt)
section
OCAMLPACKS[] += oUnit
OCAML_LIBS[] += sqlexpr
OCamlProgram(t_sqlexpr_sqlite, t_sqlexpr_sqlite)
$(addsuffixes .o .cmx .cmi .cmo, t_sqlexpr_sqlite):
section
VERSION = $`(shell oasis query Version | tail -1)
NAME = $`(string ocaml-sqlexpr-$(VERSION))
DATE = $`(shell date +%F)
BRANCH = $`(string $(VERSION)_$(DATE))
.PHONY: release
release:
git checkout -b $(BRANCH)
oasis setup
git add -f META sqlexpr.odocl Makefile _tags configure \
myocamlbuild.ml setup.ml sqlexpr.mllib sqlexpr_syntax.mllib
git commit -m "Add OASIS-generated build system."
git archive -v --prefix $(NAME)/ -o $(NAME).tar HEAD
rm -f $(NAME).tar.gz
gzip $(NAME).tar
git checkout master
git branch -D $(BRANCH)
.DEFAULT: pa_sql.cmo sqlexpr.cma sqlexpr.cmxa
.PHONY: test
test: t_sqlexpr_sqlite
./t_sqlexpr_sqlite
.SUBDIRS: src tests/ppx tests/syntax
.PHONY: clean
clean:
rm -f $(filter-proper-targets $(ls R, .)) *.s *.annot *.so *.a
# vim: set sw=4 et:
ocaml-sqlexpr is a simple library and syntax extension for type-safe,
convenient execution of SQL statements, currently compatible with Sqlite3.
The latest version can be found at https://github.com/mfp/ocaml-sqlexpr
Sqlexpr features:
* automated prepared statement caching, param binding, data extraction, error
checking (including automatic stmt reset to avoid BUSY/LOCKED errors in
subsequent queries), stmt finalization on db close, etc.
* HOFs like iter, fold, transaction
* support for different concurrency models: everything is functorized over a
THREAD monad, so you can for instance do concurrent folds/iters with Lwt
* support for SQL stmt syntax checks and some extra semantic checking (column
names, etc)
Sqlexpr is used as follows:
module Sqlexpr = Sqlexpr_sqlite.Make(Sqlexpr_concurrency.Id)
module S = Sqlexpr
let () =
let db = S.open_db "foo.db" in
S.iter db
(fun (n, p) -> Printf.printf "User %S, password %S\n" n p)
sqlc"SELECT @s{login}, @s{password} FROM users";
List.iter
(fun (n, p) -> S.execute db sqlc"INSERT INTO users VALUES(%s, %s)" n p)
[
"coder24", "badpass";
"tokyo3", "12345"
]
See also example.ml.
Dependencies
============
csv, batteries, sqlite3, estring, lwt (>= 2.2.0), lwt.syntax, lwt.unix,
unix, threads
Syntax extension
================
ocaml-sqlexpr includes a syntax extension to build type-safe SQL
statements/expressions:
sql"..." denotes a SQL statement/expression
sqlc"..." denotes a SQL statement/expression that is to be cached
sql_check"sqlite" returns a tuple of functions to initialize, check the
validity of the SQL statements/expressions and
check against an auto-initialized temporary database.
sqlinit"..." is equivalent to sql"...", but the statement will be added
to the list of statements to be executed in the automatically
generated initialization function
sql_check"sqlite" is used as follows:
let auto_init_db, check_db, auto_check_db = sql_check"sqlite"
which creates 3 functions
val auto_init_db : Sqlite3.db -> Format.formatter -> bool
val check_db : Sqlite3.db -> Format.formatter -> bool
val auto_check_db : Format.formatter -> bool
each of them returns [false] on error, and writes the error messages to the
provided formatter.
SQL statement/expression syntax
-------------------------------
sql/sqlc literals are similar to Printf's format strings and their precise
types depend on their contents. They accept input parameters (similarly to
Printf) and, in the case of SQL expressions, their execution will yield a
tuple whose type is determined by the output parameters.
Input parameters are denoted with %X where X is one of:
input parameter OCaml type
--------------- ----------
%d int
%l Int32.t
%L Int64.t
%s string
%S string (handled as BLOB by SQLite)
%f float
%b bool
%a ('a -> string) (resulting string handled as BLOB by SQLite)
A literal '%' is denoted with '%%'.
A parameter is made nullable (turning the OCaml type into a [_ option]) by
appending a '?', e.g. '%d?'.
Output parameters are denoted with @X{SQL expression} where X is one of:
output parameter OCaml type
---------------- ----------
@d int
@l Int32.t
@L Int64.t
@s string
@S string (handled as BLOB by SQLite)
@f float
@b bool
A literal '@' is denoted with '@@'.
As in the case of input parameters, output parameters can be made nullable by
appending a '?'.
A sql"..." or sqlc"..." literal is of type [_ statement] if it has no output
parameters, and of type [_ expression] if it has at least one.
Examples:
sql"SELECT @s{name} FROM users" is an expression
sql"SELECT @s{name} FROM users WHERE id = %d" is an expression
sql"SELECT @s{name}, @s{email} FROM users" is an expression
sql"DELETE FROM users WHERE id = %d" is a statement
Statements are executed with [execute] or [insert] (which returns the id of
the new row); expressions are "selected" with a function from the [select*]
family or a HOF like [iter] or [fold].
Examples:
module Sqlexpr = Sqlexpr_sqlite.Make(Sqlexpr_concurrency.Id)
module S = Sqlexpr
let insert_user_stmt =
sqlc"INSERT INTO users(login, password, email) VALUES(%s, %s, %s?)"
let insert_user db ~login ?email ~password =
S.execute db insert_user_stmt login password email
(* insert user and return ID; we use partial application here *)
let new_user_id db = S.insert db insert_user_stmt
let get_password db =
S.select_one db sqlc"SELECT @s{password} FROM users WHERE login = %s"
let get_email db =
S.select_one db sqlc"SELECT @s?{email} FROM users WHERE login = %s"
let iter_users db f =
S.iter db f sqlc"SELECT @L{id}, @s{login}, @s{password}, @s?{email}
FROM users"
**ocaml-sqlexpr** is a simple library and syntax extension for type-safe,
convenient execution of SQL statements, currently compatible with Sqlite3.
The latest version can be found at https://github.com/mfp/ocaml-sqlexpr
**ocaml-sqlexpr** features:
* automated prepared statement caching, parameter binding, data extraction, error
checking (including automatic statement reset to avoid BUSY/LOCKED errors in
subsequent queries), statement finalization on database close, etc.
* higher order functions like *iter*, *fold*, *transaction*
* support for different concurrency models: everything is functorized over a
THREAD monad, so you can for instance do concurrent treatmments with Lwt
* support for SQL statement syntax checks and some extra semantic checking (column
names, etc.)
**ocaml-sqlexpr** is used as follows:
```ocaml
module Sqlexpr = Sqlexpr_sqlite.Make(Sqlexpr_concurrency.Id)
module S = Sqlexpr
let () =
let db = S.open_db "foo.db" in
S.iter db
(fun (n, p) -> Printf.printf "User %S, password %S\n" n p)
sqlc"SELECT @s{login}, @s{password} FROM users";
List.iter
(fun (n, p) -> S.execute db sqlc"INSERT INTO users VALUES(%s, %s)" n p)
[
"coder24", "badpass";
"tokyo3", "12345"
]
```
See also the example file `example.ml`.
## Dependencies
* cppo
* csv
* lwt (>= 2.2.0)
* lwt.syntax
* lwt.unix
* ppx_tools
* re
* sqlite3
* threads
* unix
## Optional Dependencies
* camlp4
* estring
The optional dependencies allow building of the Camlp4 syntax extension.
## Camlp4 syntax extension
**ocaml-sqlexpr** includes a syntax extension to build type-safe SQL
statements and expressions:
- `sql"..."` denotes a SQL statement or expression
- `sqlc"..."` denotes a SQL statement or expression that is to be cached
- `sql_check"sqlite"` returns a tuple of functions to initialize, check the
validity of the SQL statements or expressions and
check against an auto-initialized temporary database.
- `sqlinit"..."` is equivalent to `sql"..."`, but the statement will be added
to the list of statements to be executed in the automatically
generated initialization function
`sql_check"sqlite"` is used as follows:
```ocaml
let auto_init_db, check_db, auto_check_db = sql_check"sqlite"
```
which creates 3 functions
```ocaml
val auto_init_db : Sqlite3.db -> Format.formatter -> bool
val check_db : Sqlite3.db -> Format.formatter -> bool
val auto_check_db : Format.formatter -> bool
```
each of them returns `false` on error, and writes the error messages to the
provided formatter.
## PPX syntax extension
In addition to the camlp4-based syntax extension, **ocaml-sqlexpr** includes a
syntax extension using extension points (ppx). The conversion from camlp4 to
ppx is as follows:
- `[%sql "..."]` corresponds to `sql"..."`
- `[%sqlc "..."]` corresponds to `sqlc"..."`
- `[%sqlcheck "sqlite"]` corresponds to `sql_check"sqlite"`
- `[%sqlinit "..."]` corresponds to `sqlinit"..."`
## SQL statement/expression syntax
Literals marked with `sql` or `sqlc` are similar to Printf's format strings and their precise
types depend on their contents. They accept input parameters (similarly to
Printf) and, in the case of SQL expressions, their execution will yield a
tuple whose type is determined by the output parameters.
Input parameters are denoted with `%X` where `X` is one of:
Input parameter | OCaml type
-----------------|-----------
%d | int
%l | Int32.t
%L | Int64.t
%s | string
%S | string (handled as BLOB by SQLite)
%f | float
%b | bool
%a | ('a -> string) (resulting string handled as BLOB by SQLite)
A literal `%` is denoted with `%%`.
A parameter is made nullable (turning the OCaml type into a `_ option`) by
appending a `?`, e.g. `%d?`.
Output parameters are denoted with `@X{SQL expression}` where `X` is one of:
Output parameter | OCaml type
---------------- | ----------
@d | int
@l | Int32.t
@L | Int64.t
@s | string
@S | string (handled as BLOB by SQLite)
@f | float
@b | bool
A literal `@` is denoted with `@@`
As in the case of input parameters, output parameters can be made nullable by
appending a `?`.
A `sql"..."` or `sqlc"..."` literal is of type `_ statement` if it has no output
parameters, and of type `_ expression` if it has at least one.
### Examples
```ocaml
sql"SELECT @s{name} FROM users" is an expression
sql"SELECT @s{name} FROM users WHERE id = %d" is an expression
sql"SELECT @s{name}, @s{email} FROM users" is an expression
sql"DELETE FROM users WHERE id = %d" is a statement
```
Statements are executed with `execute` or `insert` (which returns the id of
the new row); expressions are “selected” with a function from the `select*`
family or a higher order function like `iter` or `fold`.
### Examples
```ocaml
module Sqlexpr = Sqlexpr_sqlite.Make(Sqlexpr_concurrency.Id)
module S = Sqlexpr
let insert_user_stmt =
sqlc"INSERT INTO users(login, password, email) VALUES(%s, %s, %s?)"
let insert_user db ~login ?email ~password =
S.execute db insert_user_stmt login password email
(* insert user and return ID; we use partial application here *)
let new_user_id db = S.insert db insert_user_stmt
let get_password db =
S.select_one db sqlc"SELECT @s{password} FROM users WHERE login = %s"
let get_email db =
S.select_one db sqlc"SELECT @s?{email} FROM users WHERE login = %s"
let iter_users db f =
S.iter db f sqlc"SELECT @L{id}, @s{login}, @s{password}, @s?{email}
FROM users"
```
### Test and Sample Build Instructions
Example Camlp4 Code:
```
ocamlfind ocamlc -package sqlexpr,pa_sqlexpr -syntax camlp4o -linkpkg -thread -o sqlexpr_camlp4 tests/syntax/example.ml
```
Example PPX Code
```
ocamlfind ocamlc -package sqlexpr.ppx -linkpkg -thread -o sqlexpr_ppx tests/ppx/example.ml
```
or
```
jbuilder build tests/ppx/example.exe
```
Camlp4 based tests:
```
ocamlfind ocamlc -package sqlexpr,pa_sqlexpr,lwt.syntax,oUnit -syntax camlp4o -linkpkg -thread -o sqlexpr_camlp4_test tests/syntax/t_sqlexpr.ml
```
PPX based tests:
```
ocamlfind ocamlc -package sqlexpr.ppx,lwt_ppx,oUnit -ppxopt lwt_ppx,-no-debug -linkpkg -thread -o sqlexpr_ppx_test tests/ppx/t_sqlexpr.ml
```
or
```
jbuilder runtest ./tests/ppx
```
OASISFormat: 0.3
Name: ocaml-sqlexpr
Version: 0.5.5
Synopsis: Type-safe, convenient SQLite database access.
Authors: Mauricio Fernandez <mfp@acm.org>
Maintainers: Mauricio Fernandez <mfp@acm.org>
License: LGPL-2.1 with OCaml linking exception
Plugins: DevFiles (0.3), META (0.3)
BuildTools: ocamlbuild
Homepage: http://github.com/mfp/ocaml-sqlexpr
Description:
Minimalistic library and syntax extension for type-safe, convenient execution
of SQL statements. Currently compatible with Sqlite3.
.
Sqlexpr features:
.
* automated prepared statement caching, param binding, data extraction, error
checking (including automatic stmt reset to avoid BUSY/LOCKED errors in
subsequent queries), stmt finalization on db close, etc.
.
* HOFs like iter, fold, transaction
.
* support for different concurrency models: everything is functorized over a
THREAD monad, so you can for instance do concurrent folds/iters with Lwt
.
* support for SQL stmt syntax checks and some extra semantic checking (column
names, etc)
SourceRepository github
Type: git
Location: git://github.com/mfp/ocaml-sqlexpr.git
Library sqlexpr
Path: .
BuildTools: ocamlbuild
Modules: Sqlexpr_concurrency,
Sqlexpr_sqlite,
Sqlexpr_sqlite_lwt
BuildDepends: csv, batteries, sqlite3, estring, lwt (>= 2.2.0), lwt.syntax, lwt.unix,
unix, threads
XMETADescription: SQLite database access.
Library "sqlexpr_syntax"
Path: .
FindlibName: syntax
FindlibParent: sqlexpr
Modules: Pa_sql
BuildDepends: camlp4.lib, camlp4.quotations.r, estring
XMETADescription: Syntax extension for SQL statements/expressions
XMETAType: syntax
XMETARequires: camlp4, estring
Document sqlexpr
Title: API reference for Sqlexpr
Type: ocamlbuild (0.3)
InstallDir: $htmldir/sqlexpr
BuildTools+: ocamldoc
XOCamlbuildPath: .
XOCamlbuildLibraries: sqlexpr
<**/*.ml>: syntax_camlp4o
# OASIS_START
# DO NOT EDIT (digest: dfffe6ec960f8ff3b4403d34c7548c58)
# Ignore VCS directories, you can use the same kind of rule outside
# OASIS_START/STOP if you want to exclude directories that contains
# useless stuff for the build process
<**/.svn>: -traverse
<**/.svn>: not_hygienic
".bzr": -traverse
".bzr": not_hygienic
".hg": -traverse
".hg": not_hygienic
".git": -traverse
".git": not_hygienic
"_darcs": -traverse
"_darcs": not_hygienic
# Library sqlexpr_syntax
"sqlexpr_syntax.cmxs": use_sqlexpr_syntax
<*.ml{,i}>: pkg_camlp4.quotations.r
<*.ml{,i}>: pkg_camlp4.lib
# Library sqlexpr
"sqlexpr.cmxs": use_sqlexpr
<*.ml{,i}>: pkg_unix
<*.ml{,i}>: pkg_threads
<*.ml{,i}>: pkg_sqlite3
<*.ml{,i}>: pkg_lwt.unix
<*.ml{,i}>: pkg_lwt.syntax
<*.ml{,i}>: pkg_lwt
<*.ml{,i}>: pkg_estring
<*.ml{,i}>: pkg_csv
<*.ml{,i}>: pkg_batteries
# OASIS_STOP
#!/bin/sh
# OASIS_START
# DO NOT EDIT (digest: 425187ed8bfdbdd207fd76392dd243a7)
set -e
FST=true
for i in "$@"; do
if $FST; then
set --
FST=false
fi
case $i in
--*=*)
ARG=${i%%=*}
VAL=${i##*=}
set -- "$@" "$ARG" "$VAL"
;;
*)
set -- "$@" "$i"
;;
esac
done
ocaml setup.ml -configure "$@"
# OASIS_STOP
(* OASIS_START *)
(* DO NOT EDIT (digest: 4b0b54727d86f5e35ee2bb2cd5d0d6c7) *)
module OASISGettext = struct
# 21 "/home/mfp/src/ocsigen-bundle-2.2.2/others/oasis-0.3.0~rc3/src/oasis/OASISGettext.ml"
let ns_ str =
str
let s_ str =
str
let f_ (str : ('a, 'b, 'c, 'd) format4) =
str
let fn_ fmt1 fmt2 n =
if n = 1 then
fmt1^^""
else
fmt2^^""
let init =
[]
end
module OASISExpr = struct
# 21 "/home/mfp/src/ocsigen-bundle-2.2.2/others/oasis-0.3.0~rc3/src/oasis/OASISExpr.ml"
open OASISGettext
type test = string
type flag = string
type t =
| EBool of bool
| ENot of t
| EAnd of t * t
| EOr of t * t
| EFlag of flag
| ETest of test * string
type 'a choices = (t * 'a) list
let eval var_get t =
let rec eval' =
function
| EBool b ->
b
| ENot e ->
not (eval' e)
| EAnd (e1, e2) ->
(eval' e1) && (eval' e2)
| EOr (e1, e2) ->
(eval' e1) || (eval' e2)
| EFlag nm ->
let v =
var_get nm
in
assert(v = "true" || v = "false");
(v = "true")
| ETest (nm, vl) ->
let v =
var_get nm
in
(v = vl)
in
eval' t
let choose ?printer ?name var_get lst =
let rec choose_aux =
function
| (cond, vl) :: tl ->
if eval var_get cond then
vl
else
choose_aux tl
| [] ->
let str_lst =
if lst = [] then
s_ "<empty>"
else
String.concat
(s_ ", ")
(List.map
(fun (cond, vl) ->
match printer with
| Some p -> p vl
| None -> s_ "<no printer>")
lst)
in
match name with
| Some nm ->
failwith
(Printf.sprintf
(f_ "No result for the choice list '%s': %s")
nm str_lst)
| None ->
failwith
(Printf.sprintf
(f_ "No result for a choice list: %s")
str_lst)
in
choose_aux (List.rev lst)
end
module BaseEnvLight = struct
# 21 "/home/mfp/src/ocsigen-bundle-2.2.2/others/oasis-0.3.0~rc3/src/base/BaseEnvLight.ml"
module MapString = Map.Make(String)
type t = string MapString.t
let default_filename =
Filename.concat
(Sys.getcwd ())
"setup.data"
let load ?(allow_empty=false) ?(filename=default_filename) () =
if Sys.file_exists filename then
begin
let chn =
open_in_bin filename
in
let st =
Stream.of_channel chn
in
let line =
ref 1
in
let st_line =
Stream.from
(fun _ ->
try
match Stream.next st with
| '\n' -> incr line; Some '\n'
| c -> Some c
with Stream.Failure -> None)
in
let lexer =
Genlex.make_lexer ["="] st_line
in
let rec read_file mp =
match Stream.npeek 3 lexer with
| [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
Stream.junk lexer;
Stream.junk lexer;
Stream.junk lexer;
read_file (MapString.add nm value mp)
| [] ->
mp
| _ ->
failwith
(Printf.sprintf
"Malformed data file '%s' line %d"
filename !line)
in
let mp =
read_file MapString.empty
in
close_in chn;
mp
end
else if allow_empty then
begin
MapString.empty
end
else
begin
failwith
(Printf.sprintf
"Unable to load environment, the file '%s' doesn't exist."
filename)
end
let var_get name env =
let rec var_expand str =
let buff =
Buffer.create ((String.length str) * 2)
in
Buffer.add_substitute
buff
(fun var ->
try
var_expand (MapString.find var env)
with Not_found ->
failwith
(Printf.sprintf
"No variable %s defined when trying to expand %S."
var
str))
str;
Buffer.contents buff
in
var_expand (MapString.find name env)
let var_choose lst env =
OASISExpr.choose
(fun nm -> var_get nm env)
lst
end
module MyOCamlbuildFindlib = struct
# 21 "/home/mfp/src/ocsigen-bundle-2.2.2/others/oasis-0.3.0~rc3/src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml"
(** OCamlbuild extension, copied from
* http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild
* by N. Pouillard and others
*
* Updated on 2009/02/28
*
* Modified by Sylvain Le Gall
*)
open Ocamlbuild_plugin
(* these functions are not really officially exported *)
let run_and_read =
Ocamlbuild_pack.My_unix.run_and_read
let blank_sep_strings =
Ocamlbuild_pack.Lexers.blank_sep_strings
let split s ch =
let x =
ref []
in
let rec go s =
let pos =
String.index s ch
in
x := (String.before s pos)::!x;
go (String.after s (pos + 1))
in
try
go s
with Not_found -> !x
let split_nl s = split s '\n'
let before_space s =
try
String.before s (String.index s ' ')
with Not_found -> s
(* this lists all supported packages *)
let find_packages () =
List.map before_space (split_nl & run_and_read "ocamlfind list")
(* this is supposed to list available syntaxes, but I don't know how to do it. *)
let find_syntaxes () = ["camlp4o"; "camlp4r"]
(* ocamlfind command *)
let ocamlfind x = S[A"ocamlfind"; x]
let dispatch =
function
| Before_options ->
(* by using Before_options one let command line options have an higher priority *)
(* on the contrary using After_options will guarantee to have the higher priority *)
(* override default commands by ocamlfind ones *)
Options.ocamlc := ocamlfind & A"ocamlc";
Options.ocamlopt := ocamlfind & A"ocamlopt";
Options.ocamldep := ocamlfind & A"ocamldep";
Options.ocamldoc := ocamlfind & A"ocamldoc";
Options.ocamlmktop := ocamlfind & A"ocamlmktop"
| After_rules ->
(* When one link an OCaml library/binary/package, one should use -linkpkg *)
flag ["ocaml"; "link"; "program"] & A"-linkpkg";
(* For each ocamlfind package one inject the -package option when
* compiling, computing dependencies, generating documentation and
* linking. *)
List.iter
begin fun pkg ->
flag ["ocaml"; "compile"; "pkg_"^pkg] & S[A"-package"; A pkg];
flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S[A"-package"; A pkg];
flag ["ocaml"; "doc"; "pkg_"^pkg] & S[A"-package"; A pkg];
flag ["ocaml"; "link"; "pkg_"^pkg] & S[A"-package"; A pkg];
flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S[A"-package"; A pkg];
end
(find_packages ());
(* Like -package but for extensions syntax. Morover -syntax is useless
* when linking. *)
List.iter begin fun syntax ->
flag ["ocaml"; "compile"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
flag ["ocaml"; "ocamldep"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
flag ["ocaml"; "doc"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
flag ["ocaml"; "infer_interface"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
end (find_syntaxes ());
(* The default "thread" tag is not compatible with ocamlfind.
* Indeed, the default rules add the "threads.cma" or "threads.cmxa"
* options when using this tag. When using the "-linkpkg" option with
* ocamlfind, this module will then be added twice on the command line.
*
* To solve this, one approach is to add the "-thread" option when using
* the "threads" package using the previous plugin.
*)
flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]);
flag ["ocaml"; "pkg_threads"; "doc"] (S[A "-I"; A "+threads"]);
flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"])
| _ ->
()
end
module MyOCamlbuildBase = struct
# 21 "/home/mfp/src/ocsigen-bundle-2.2.2/others/oasis-0.3.0~rc3/src/plugins/ocamlbuild/MyOCamlbuildBase.ml"
(** Base functions for writing myocamlbuild.ml
@author Sylvain Le Gall
*)
open Ocamlbuild_plugin
module OC = Ocamlbuild_pack.Ocaml_compiler
type dir = string
type file = string
type name = string
type tag = string
# 56 "/home/mfp/src/ocsigen-bundle-2.2.2/others/oasis-0.3.0~rc3/src/plugins/ocamlbuild/MyOCamlbuildBase.ml"
type t =
{
lib_ocaml: (name * dir list) list;
lib_c: (name * dir * file list) list;
flags: (tag list * (spec OASISExpr.choices)) list;
(* Replace the 'dir: include' from _tags by a precise interdepends in
* directory.
*)
includes: (dir * dir list) list;
}
let env_filename =
Pathname.basename
BaseEnvLight.default_filename
let dispatch_combine lst =
fun e ->
List.iter
(fun dispatch -> dispatch e)
lst
let tag_libstubs nm =
"use_lib"^nm^"_stubs"
let nm_libstubs nm =
nm^"_stubs"
let dispatch t e =
let env =
BaseEnvLight.load
~filename:env_filename
~allow_empty:true
()
in
match e with
| Before_options ->
let no_trailing_dot s =
if String.length s >= 1 && s.[0] = '.' then
String.sub s 1 ((String.length s) - 1)
else
s
in
List.iter
(fun (opt, var) ->
try
opt := no_trailing_dot (BaseEnvLight.var_get var env)
with Not_found ->
Printf.eprintf "W: Cannot get variable %s" var)
[
Options.ext_obj, "ext_obj";
Options.ext_lib, "ext_lib";
Options.ext_dll, "ext_dll";
]
| Before_rules ->
(* TODO: move this into its own file and conditionnaly include it, if
* needed.
*)
(* OCaml cmxs rules: cmxs available in ocamlopt but not ocamlbuild.
Copied from ocaml_specific.ml in ocamlbuild sources. *)
let has_native_dynlink =
try
bool_of_string (BaseEnvLight.var_get "native_dynlink" env)
with Not_found ->
false
in
if has_native_dynlink && String.sub Sys.ocaml_version 0 4 = "3.11" then
begin
let ext_lib = !Options.ext_lib in
let ext_obj = !Options.ext_obj in
let ext_dll = !Options.ext_dll in
let x_o = "%"-.-ext_obj in
let x_a = "%"-.-ext_lib in
let x_dll = "%"-.-ext_dll in
let x_p_o = "%.p"-.-ext_obj in
let x_p_a = "%.p"-.-ext_lib in
let x_p_dll = "%.p"-.-ext_dll in
rule "ocaml: mldylib & p.cmx* & p.o* -> p.cmxs & p.so"
~tags:["ocaml"; "native"; "profile"; "shared"; "library"]
~prods:["%.p.cmxs"; x_p_dll]
~dep:"%.mldylib"
(OC.native_profile_shared_library_link_mldylib
"%.mldylib" "%.p.cmxs");
rule "ocaml: mldylib & cmx* & o* -> cmxs & so"
~tags:["ocaml"; "native"; "shared"; "library"]
~prods:["%.cmxs"; x_dll]
~dep:"%.mldylib"
(OC.native_shared_library_link_mldylib
"%.mldylib" "%.cmxs");
rule "ocaml: p.cmx & p.o -> p.cmxs & p.so"
~tags:["ocaml"; "native"; "profile"; "shared"; "library"]
~prods:["%.p.cmxs"; x_p_dll]
~deps:["%.p.cmx"; x_p_o]
(OC.native_shared_library_link ~tags:["profile"]
"%.p.cmx" "%.p.cmxs");
rule "ocaml: p.cmxa & p.a -> p.cmxs & p.so"
~tags:["ocaml"; "native"; "profile"; "shared"; "library"]
~prods:["%.p.cmxs"; x_p_dll]
~deps:["%.p.cmxa"; x_p_a]
(OC.native_shared_library_link ~tags:["profile"; "linkall"]
"%.p.cmxa" "%.p.cmxs");
rule "ocaml: cmx & o -> cmxs"
~tags:["ocaml"; "native"; "shared"; "library"]
~prods:["%.cmxs"]
~deps:["%.cmx"; x_o]
(OC.native_shared_library_link "%.cmx" "%.cmxs");
rule "ocaml: cmx & o -> cmxs & so"
~tags:["ocaml"; "native"; "shared"; "library"]
~prods:["%.cmxs"; x_dll]
~deps:["%.cmx"; x_o]
(OC.native_shared_library_link "%.cmx" "%.cmxs");
rule "ocaml: cmxa & a -> cmxs & so"
~tags:["ocaml"; "native"; "shared"; "library"]
~prods:["%.cmxs"; x_dll]
~deps:["%.cmxa"; x_a]
(OC.native_shared_library_link ~tags:["linkall"]
"%.cmxa" "%.cmxs");
end
| After_rules ->
(* Declare OCaml libraries *)
List.iter
(function
| nm, [] ->
ocaml_lib nm
| nm, dir :: tl ->
ocaml_lib ~dir:dir (dir^"/"^nm);
List.iter
(fun dir ->
List.iter
(fun str ->
flag ["ocaml"; "use_"^nm; str] (S[A"-I"; P dir]))
["compile"; "infer_interface"; "doc"])
tl)
t.lib_ocaml;
(* Declare directories dependencies, replace "include" in _tags. *)
List.iter
(fun (dir, include_dirs) ->
Pathname.define_context dir include_dirs)
t.includes;
(* Declare C libraries *)
List.iter
(fun (lib, dir, headers) ->
(* Handle C part of library *)
flag ["link"; "library"; "ocaml"; "byte"; tag_libstubs lib]
(S[A"-dllib"; A("-l"^(nm_libstubs lib)); A"-cclib";
A("-l"^(nm_libstubs lib))]);
flag ["link"; "library"; "ocaml"; "native"; tag_libstubs lib]
(S[A"-cclib"; A("-l"^(nm_libstubs lib))]);
flag ["link"; "program"; "ocaml"; "byte"; tag_libstubs lib]
(S[A"-dllib"; A("dll"^(nm_libstubs lib))]);
(* When ocaml link something that use the C library, then one
need that file to be up to date.
*)
dep ["link"; "ocaml"; "program"; tag_libstubs lib]
[dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
dep ["compile"; "ocaml"; "program"; tag_libstubs lib]
[dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
(* TODO: be more specific about what depends on headers *)
(* Depends on .h files *)
dep ["compile"; "c"]
headers;
(* Setup search path for lib *)
flag ["link"; "ocaml"; "use_"^lib]
(S[A"-I"; P(dir)]);
)
t.lib_c;
(* Add flags *)
List.iter
(fun (tags, cond_specs) ->
let spec =
BaseEnvLight.var_choose cond_specs env
in
flag tags & spec)
t.flags
| _ ->
()
let dispatch_default t =
dispatch_combine
[
dispatch t;
MyOCamlbuildFindlib.dispatch;
]
end
open Ocamlbuild_plugin;;
let package_default =
{
MyOCamlbuildBase.lib_ocaml = [("sqlexpr_syntax", []); ("sqlexpr", [])];
lib_c = [];
flags = [];
includes = [];
}
;;
let dispatch_default = MyOCamlbuildBase.dispatch_default package_default;;
# 559 "myocamlbuild.ml"
(* OASIS_STOP *)
Ocamlbuild_plugin.dispatch dispatch_default;;
opam-version: "1.2"
maintainer: "mfp@acm.org"
authors: ["Mauricio Fernandez <mfp@acm.org>"]
license: "LGPL-2.1 with OCaml linking exception"
homepage: "http://github.com/mfp/ocaml-sqlexpr"
dev-repo: "https://github.com/mfp/ocaml-sqlexpr.git"
bug-reports: "https://github.com/mfp/ocaml-sqlexpr/issues"
build: [
[ "jbuilder" "build" "-p" name "-j" jobs ]
]
depends: [
"jbuilder" {build}
"sqlexpr"
"estring"
"camlp4"
]
opam-version: "1.2"
maintainer: "mfp@acm.org"
authors: ["Mauricio Fernandez <mfp@acm.org>"]
license: "LGPL-2.1 with OCaml linking exception"
homepage: "http://github.com/mfp/ocaml-sqlexpr"
dev-repo: "https://github.com/mfp/ocaml-sqlexpr.git"
bug-reports: "https://github.com/mfp/ocaml-sqlexpr/issues"
doc: "doc"
build: [
[ "jbuilder" "build" "-p" name "-j" jobs ]
]
build-test: [["jbuilder" "runtest" "-p" name "-j" jobs]]
depends: [
"jbuilder" {build}
"ppx_tools_versioned"
"ppx_core"
"ocaml-migrate-parsetree"
"base-unix"
"re" {build & >= "1.3.0"}
"ounit" {test}
"lwt" {test}
]
This diff is collapsed.