Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file check.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180(* macaque : check.ml
MaCaQue : Macros for Caml Queries
Copyright (C) 2009 Gabriel Scherer, Jérôme Vouillon
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; see the file LICENSE. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*)openSqlopenSql_internalsopenSql_printersopenPrintfletperform_checkcheck_descriptionquerydescription=letdbh=PGOCaml.connect()inletcheck_result=try`Result(check_description(querydbhdescription))withexn->`ExnexninPGOCaml.closedbh;matchcheck_resultwith|`Resultres->res|`Exnexn->raiseexnletcheck_table_descriptiontable_namedescrpgsql_descr=letcorrect=reftrueinletcheckdescrfield=letfield_name=field#!column_nameinletfield_type,descr=trySome(List.assocfield_namedescr),List.remove_assocfield_namedescrwithNot_found->None,descrinmatchfield_typewith|None->eprintf"SQL Check Warning : In table %s, field %s undescribed\n"table_namefield_name;descr|Somefield_type->letatom_type=atom_type_of_stringfield#!data_typein(matchfield_typewith|Nullable_whennotfield#!is_nullable->correct:=false;eprintf"SQL Check Error : In table %s, field %s \
is described as NULL but is NOT NULL\n"table_namefield_name|Non_nullable_whenfield#!is_nullable->correct:=false;eprintf"SQL Check Error : In table %s, field %s \
is described as NOT NULL but is NULL\n"table_namefield_name|_->());(matchfield_typewith|Nullable(Somet)|Non_nullabletwhent<>atom_type->correct:=false;eprintf"SQL Check Error : In table %s, field %s \
has incompatible types :\n\
\t%s in description, %s in table\n"table_namefield_name(string_of_atom_typet)field#!data_type|_->());descrinletleft_descr=List.fold_leftcheckdescrpgsql_descrinList.iter(fun(field_name,_)->correct:=false;eprintf"SQL Check Error : In table %s, field %s is decribed \
but does not exists in the PGSQL database\n"table_namefield_name)left_descr;ifnot!correctthenfailwith(sprintf"SQL Check : Coherence check of table %s \
against the PGSQL database failed."table_name)elseeprintf"SQL Check : Table %s description \
is coherent with the PGSQL database.\n"table_name;flushstderr(* we constrain on ('a, _ writable) Sql.view, because non_writable
views may not be actual tables in the SQL base, whereas _ writable
views always are *)letcheck_table(table:('a,_writable)Sql.view)=(* we are forced to break the abstraction, as the user will send in
Sql values, and we need an Inner_sql value to introspect *)let(table:Sql_internals.view)=Obj.magictableinlet(schema,table_name)asname=matchtable.datawith|Tablet->t.name|Selection_|View_op_->invalid_arg"check_table"inletlong_name=string_of_table_namenameinletschema=matchschemawith|None->"public"|Someschema->schemainletpgsql_columns=<:table<information_schema.columns(table_schematextNOTNULL,table_nametextNOTNULL,column_nametextNOTNULL,data_typetextNOTNULL,is_nullabletextNOTNULL)>>inlettable_descr=<<{info.column_name;info.data_type;is_nullable=(info.is_nullable="YES")}|infoin$pgsql_columns$;info.table_schema=$string:schema$;info.table_name=$string:table_name$>>inperform_check(check_table_descriptionlong_nametable.descr)(Query.view?log:None)table_descrletcheck_sequence_descriptionseq_namedescr_typedescr=letcorrect=reftrueinbeginmatchdescrwith|None->correct:=false;eprintf"SQL Check Error : Sequence %s is described \
but does not exists in the PGSQL database.\n"seq_name|Somedescr->letreal_type=matchdescr#!numeric_precisionwith|16l->SomeTInt16|32l->SomeTInt32|64l->SomeTInt64|p->correct:=false;eprintf"SQL Check Error : unsupported \
numeric precision : %ld.\n"p;Noneinmatchreal_typewith|None->()|Somereal_type->ifreal_type<>descr_typethenbegincorrect:=false;eprintf"SQL Check Error : Sequence %s type \
is described as %s but is %s.\n"seq_name(string_of_atom_typedescr_type)(string_of_atom_typereal_type)endend;ifnot!correctthenfailwith(sprintf"SQL Check : Coherence check of sequence %s \
against the PGSQL database failed."seq_name)elseeprintf"SQL Check : Sequence %s description \
is coherent with the PGSQL database.\n"seq_name;flushstderrletcheck_sequence(seq:'aSql.sequence)=(* see check_table Obj.magic comment *)let(seq:'aSql_public.sequence)=Obj.magicseqinlet(name,typ)=seqinletpgsql_sequences=<:table<information_schema.sequences(sequence_nametextNOTNULL,numeric_precisionintegerNOTNULL)>>inletsequence_description=<<t|tin$pgsql_sequences$;t.sequence_name=$string:name$>>inperform_check(check_sequence_descriptionnametyp)(Query.view_opt?log:None)sequence_description