packages feed

hsSqlite3 0.0.6 → 0.1

raw patch · 10 files changed

+859/−653 lines, 10 filesdep +bytestringdep +mtldep ~basedep ~bindings-sqlite3dep ~utf8-stringsetup-changed

Dependencies added: bytestring, mtl

Dependency ranges changed: base, bindings-sqlite3, utf8-string

Files

@@ -0,0 +1,426 @@+GNU Lesser General Public License++Version 2.1, February 1999++    Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place,+    Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and+    distribute verbatim copies of this license document, but changing it is not+    allowed.++    [This is the first released version of the Lesser GPL. It also counts as+    the successor of the GNU Library Public License, version 2, hence the+    version number 2.1.]++Preamble++The licenses for most software are designed to take away your freedom to share+and change it. By contrast, the GNU General Public Licenses are intended to+guarantee your freedom to share and change free software--to make sure the+software is free for all its users.++This license, the Lesser General Public License, applies to some specially+designated software packages--typically libraries--of the Free Software+Foundation and other authors who decide to use it. You can use it too, but we+suggest you first think carefully about whether this license or the ordinary+General Public License is the better strategy to use in any particular case,+based on the explanations below.++When we speak of free software, we are referring to freedom of use, not price.+Our General Public Licenses are designed to make sure that you have the freedom+to distribute copies of free software (and charge for this service if you+wish); that you receive source code or can get it if you want it; that you can+change the software and use pieces of it in new free programs; and that you are+informed that you can do these things.++To protect your rights, we need to make restrictions that forbid distributors+to deny you these rights or to ask you to surrender these rights. These+restrictions translate to certain responsibilities for you if you distribute+copies of the library or if you modify it.++For example, if you distribute copies of the library, whether gratis or for a+fee, you must give the recipients all the rights that we gave you. You must+make sure that they, too, receive or can get the source code. If you link other+code with the library, you must provide complete object files to the+recipients, so that they can relink them with the library after making changes+to the library and recompiling it. And you must show them these terms so they+know their rights.++We protect your rights with a two-step method: (1) we copyright the library,+and (2) we offer you this license, which gives you legal permission to copy,+distribute and/or modify the library.++To protect each distributor, we want to make it very clear that there is no+warranty for the free library. Also, if the library is modified by someone else+and passed on, the recipients should know that what they have is not the+original version, so that the original author's reputation will not be affected+by problems that might be introduced by others.++Finally, software patents pose a constant threat to the existence of any free+program. We wish to make sure that a company cannot effectively restrict the+users of a free program by obtaining a restrictive license from a patent+holder. Therefore, we insist that any patent license obtained for a version of+the library must be consistent with the full freedom of use specified in this+license.++Most GNU software, including some libraries, is covered by the ordinary GNU+General Public License. This license, the GNU Lesser General Public License,+applies to certain designated libraries, and is quite different from the+ordinary General Public License. We use this license for certain libraries in+order to permit linking those libraries into non-free programs.++When a program is linked with a library, whether statically or using a shared+library, the combination of the two is legally speaking a combined work, a+derivative of the original library. The ordinary General Public License+therefore permits such linking only if the entire combination fits its criteria+of freedom. The Lesser General Public License permits more lax criteria for+linking other code with the library.++We call this license the "Lesser" General Public License because it does Less+to protect the user's freedom than the ordinary General Public License. It also+provides other free software developers Less of an advantage over competing+non-free programs. These disadvantages are the reason we use the ordinary+General Public License for many libraries. However, the Lesser license provides+advantages in certain special circumstances.++For example, on rare occasions, there may be a special need to encourage the+widest possible use of a certain library, so that it becomes a de-facto+standard. To achieve this, non-free programs must be allowed to use the+library. A more frequent case is that a free library does the same job as+widely used non-free libraries. In this case, there is little to gain by+limiting the free library to free software only, so we use the Lesser General+Public License.++In other cases, permission to use a particular library in non-free programs+enables a greater number of people to use a large body of free software. For+example, permission to use the GNU C Library in non-free programs enables many+more people to use the whole GNU operating system, as well as its variant, the+GNU/Linux operating system.++Although the Lesser General Public License is Less protective of the users'+freedom, it does ensure that the user of a program that is linked with the+Library has the freedom and the wherewithal to run that program using a+modified version of the Library.++The precise terms and conditions for copying, distribution and modification+follow. Pay close attention to the difference between a "work based on the+library" and a "work that uses the library". The former contains code derived+from the library, whereas the latter must be combined with the library in order+to run.++TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION++0. This License Agreement applies to any software library or other program+which contains a notice placed by the copyright holder or other authorized+party saying it may be distributed under the terms of this Lesser General+Public License (also called "this License"). Each licensee is addressed as+"you".++A "library" means a collection of software functions and/or data prepared so as+to be conveniently linked with application programs (which use some of those+functions and data) to form executables.++The "Library", below, refers to any such software library or work which has+been distributed under these terms. A "work based on the Library" means either+the Library or any derivative work under copyright law: that is to say, a work+containing the Library or a portion of it, either verbatim or with+modifications and/or translated straightforwardly into another language.+(Hereinafter, translation is included without limitation in the term+"modification".)++"Source code" for a work means the preferred form of the work for making+modifications to it. For a library, complete source code means all the source+code for all modules it contains, plus any associated interface definition+files, plus the scripts used to control compilation and installation of the+library.++Activities other than copying, distribution and modification are not covered by+this License; they are outside its scope. The act of running a program using+the Library is not restricted, and output from such a program is covered only+if its contents constitute a work based on the Library (independent of the use+of the Library in a tool for writing it). Whether that is true depends on what+the Library does and what the program that uses the Library does.++1. You may copy and distribute verbatim copies of the Library's complete source+code as you receive it, in any medium, provided that you conspicuously and+appropriately publish on each copy an appropriate copyright notice and+disclaimer of warranty; keep intact all the notices that refer to this License+and to the absence of any warranty; and distribute a copy of this License along+with the Library.++You may charge a fee for the physical act of transferring a copy, and you may+at your option offer warranty protection in exchange for a fee.++2. You may modify your copy or copies of the Library or any portion of it, thus+forming a work based on the Library, and copy and distribute such modifications+or work under the terms of Section 1 above, provided that you also meet all of+these conditions:++    a) The modified work must itself be a software library.++    b) You must cause the files modified to carry prominent notices stating+    that you changed the files and the date of any change.++    c) You must cause the whole of the work to be licensed at no charge to all+    third parties under the terms of this License.++    d) If a facility in the modified Library refers to a function or a table of+    data to be supplied by an application program that uses the facility, other+    than as an argument passed when the facility is invoked, then you must make+    a good faith effort to ensure that, in the event an application does not+    supply such function or table, the facility still operates, and performs+    whatever part of its purpose remains meaningful.++    (For example, a function in a library to compute square roots has a purpose+    that is entirely well-defined independent of the application. Therefore,+    Subsection 2d requires that any application-supplied function or table used+    by this function must be optional: if the application does not supply it,+    the square root function must still compute square roots.)++    These requirements apply to the modified work as a whole. If identifiable+    sections of that work are not derived from the Library, and can be+    reasonably considered independent and separate works in themselves, then+    this License, and its terms, do not apply to those sections when you+    distribute them as separate works. But when you distribute the same+    sections as part of a whole which is a work based on the Library, the+    distribution of the whole must be on the terms of this License, whose+    permissions for other licensees extend to the entire whole, and thus to+    each and every part regardless of who wrote it.++    Thus, it is not the intent of this section to claim rights or contest your+    rights to work written entirely by you; rather, the intent is to exercise+    the right to control the distribution of derivative or collective works+    based on the Library.++    In addition, mere aggregation of another work not based on the Library with+    the Library (or with a work based on the Library) on a volume of a storage+    or distribution medium does not bring the other work under the scope of+    this License.++3. You may opt to apply the terms of the ordinary GNU General Public License+instead of this License to a given copy of the Library. To do this, you must+alter all the notices that refer to this License, so that they refer to the+ordinary GNU General Public License, version 2, instead of to this License. (If+a newer version than version 2 of the ordinary GNU General Public License has+appeared, then you can specify that version instead if you wish.) Do not make+any other change in these notices.++Once this change is made in a given copy, it is irreversible for that copy, so+the ordinary GNU General Public License applies to all subsequent copies and+derivative works made from that copy.++This option is useful when you wish to copy part of the code of the Library+into a program that is not a library.++4. You may copy and distribute the Library (or a portion or derivative of it,+under Section 2) in object code or executable form under the terms of Sections+1 and 2 above provided that you accompany it with the complete corresponding+machine-readable source code, which must be distributed under the terms of+Sections 1 and 2 above on a medium customarily used for software interchange.++If distribution of object code is made by offering access to copy from a+designated place, then offering equivalent access to copy the source code from+the same place satisfies the requirement to distribute the source code, even+though third parties are not compelled to copy the source along with the object+code.++5. A program that contains no derivative of any portion of the Library, but is+designed to work with the Library by being compiled or linked with it, is+called a "work that uses the Library". Such a work, in isolation, is not a+derivative work of the Library, and therefore falls outside the scope of this+License.++However, linking a "work that uses the Library" with the Library creates an+executable that is a derivative of the Library (because it contains portions of+the Library), rather than a "work that uses the library". The executable is+therefore covered by this License. Section 6 states terms for distribution of+such executables.++When a "work that uses the Library" uses material from a header file that is+part of the Library, the object code for the work may be a derivative work of+the Library even though the source code is not. Whether this is true is+especially significant if the work can be linked without the Library, or if the+work is itself a library. The threshold for this to be true is not precisely+defined by law.++If such an object file uses only numerical parameters, data structure layouts+and accessors, and small macros and small inline functions (ten lines or less+in length), then the use of the object file is unrestricted, regardless of+whether it is legally a derivative work. (Executables containing this object+code plus portions of the Library will still fall under Section 6.)++Otherwise, if the work is a derivative of the Library, you may distribute the+object code for the work under the terms of Section 6. Any executables+containing that work also fall under Section 6, whether or not they are linked+directly with the Library itself.++6. As an exception to the Sections above, you may also combine or link a "work+that uses the Library" with the Library to produce a work containing portions+of the Library, and distribute that work under terms of your choice, provided+that the terms permit modification of the work for the customer's own use and+reverse engineering for debugging such modifications.++You must give prominent notice with each copy of the work that the Library is+used in it and that the Library and its use are covered by this License. You+must supply a copy of this License. If the work during execution displays+copyright notices, you must include the copyright notice for the Library among+them, as well as a reference directing the user to the copy of this License.+Also, you must do one of these things:++    a) Accompany the work with the complete corresponding machine-readable+    source code for the Library including whatever changes were used in the+    work (which must be distributed under Sections 1 and 2 above); and, if the+    work is an executable linked with the Library, with the complete+    machine-readable "work that uses the Library", as object code and/or source+    code, so that the user can modify the Library and then relink to produce a+    modified executable containing the modified Library. (It is understood that+    the user who changes the contents of definitions files in the Library will+    not necessarily be able to recompile the application to use the modified+    definitions.)++    b) Use a suitable shared library mechanism for linking with the Library. A+    suitable mechanism is one that (1) uses at run time a copy of the library+    already present on the user's computer system, rather than copying library+    functions into the executable, and (2) will operate properly with a+    modified version of the library, if the user installs one, as long as the+    modified version is interface-compatible with the version that the work was+    made with.++    c) Accompany the work with a written offer, valid for at least three years,+    to give the same user the materials specified in Subsection 6a, above, for+    a charge no more than the cost of performing this distribution.++    d) If distribution of the work is made by offering access to copy from a+    designated place, offer equivalent access to copy the above specified+    materials from the same place.++    e) Verify that the user has already received a copy of these materials or+    that you have already sent this user a copy.++For an executable, the required form of the "work that uses the Library" must+include any data and utility programs needed for reproducing the executable+from it. However, as a special exception, the materials to be distributed need+not include anything that is normally distributed (in either source or binary+form) with the major components (compiler, kernel, and so on) of the operating+system on which the executable runs, unless that component itself accompanies+the executable.++It may happen that this requirement contradicts the license restrictions of+other proprietary libraries that do not normally accompany the operating+system. Such a contradiction means you cannot use both them and the Library+together in an executable that you distribute.++7. You may place library facilities that are a work based on the Library+side-by-side in a single library together with other library facilities not+covered by this License, and distribute such a combined library, provided that+the separate distribution of the work based on the Library and of the other+library facilities is otherwise permitted, and provided that you do these two+things:++    a) Accompany the combined library with a copy of the same work based on the+    Library, uncombined with any other library facilities. This must be+    distributed under the terms of the Sections above.++    b) Give prominent notice with the combined library of the fact that part of+    it is a work based on the Library, and explaining where to find the+    accompanying uncombined form of the same work.++8. You may not copy, modify, sublicense, link with, or distribute the Library+except as expressly provided under this License. Any attempt otherwise to copy,+modify, sublicense, link with, or distribute the Library is void, and will+automatically terminate your rights under this License. However, parties who+have received copies, or rights, from you under this License will not have+their licenses terminated so long as such parties remain in full compliance.++9. You are not required to accept this License, since you have not signed it.+However, nothing else grants you permission to modify or distribute the Library+or its derivative works. These actions are prohibited by law if you do not+accept this License. Therefore, by modifying or distributing the Library (or+any work based on the Library), you indicate your acceptance of this License to+do so, and all its terms and conditions for copying, distributing or modifying+the Library or works based on it.++10. Each time you redistribute the Library (or any work based on the Library),+the recipient automatically receives a license from the original licensor to+copy, distribute, link with or modify the Library subject to these terms and+conditions. You may not impose any further restrictions on the recipients'+exercise of the rights granted herein. You are not responsible for enforcing+compliance by third parties with this License.++11. If, as a consequence of a court judgment or allegation of patent+infringement or for any other reason (not limited to patent issues), conditions+are imposed on you (whether by court order, agreement or otherwise) that+contradict the conditions of this License, they do not excuse you from the+conditions of this License. If you cannot distribute so as to satisfy+simultaneously your obligations under this License and any other pertinent+obligations, then as a consequence you may not distribute the Library at all.+For example, if a patent license would not permit royalty-free redistribution+of the Library by all those who receive copies directly or indirectly through+you, then the only way you could satisfy both it and this License would be to+refrain entirely from distribution of the Library.++If any portion of this section is held invalid or unenforceable under any+particular circumstance, the balance of the section is intended to apply, and+the section as a whole is intended to apply in other circumstances.++It is not the purpose of this section to induce you to infringe any patents or+other property right claims or to contest validity of any such claims; this+section has the sole purpose of protecting the integrity of the free software+distribution system which is implemented by public license practices. Many+people have made generous contributions to the wide range of software+distributed through that system in reliance on consistent application of that+system; it is up to the author/donor to decide if he or she is willing to+distribute software through any other system and a licensee cannot impose that+choice.++This section is intended to make thoroughly clear what is believed to be a+consequence of the rest of this License.++12. If the distribution and/or use of the Library is restricted in certain+countries either by patents or by copyrighted interfaces, the original+copyright holder who places the Library under this License may add an explicit+geographical distribution limitation excluding those countries, so that+distribution is permitted only in or among countries not thus excluded. In such+case, this License incorporates the limitation as if written in the body of+this License.++13. The Free Software Foundation may publish revised and/or new versions of the+Lesser General Public License from time to time. Such new versions will be+similar in spirit to the present version, but may differ in detail to address+new problems or concerns.++Each version is given a distinguishing version number. If the Library specifies+a version number of this License which applies to it and "any later version",+you have the option of following the terms and conditions either of that+version or of any later version published by the Free Software Foundation. If+the Library does not specify a license version number, you may choose any+version ever published by the Free Software Foundation.++14. If you wish to incorporate parts of the Library into other free programs+whose distribution conditions are incompatible with these, write to the author+to ask for permission. For software which is copyrighted by the Free Software+Foundation, write to the Free Software Foundation; we sometimes make exceptions+for this. Our decision will be guided by the two goals of preserving the free+status of all derivatives of our free software and of promoting the sharing and+reuse of software generally.++NO WARRANTY++15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR+THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE+LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND+PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU+ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.++16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE+LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR+INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.++END OF TERMS AND CONDITIONS
− LICENSE
@@ -1,31 +0,0 @@-Copyright (c) 2007, Evgeny Jukov-Copyright (c) 2008-2009, Maurício C. Antunes-All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are-met:--    * Redistributions of source code must retain the above copyright-      notice, this list of conditions and the following disclaimer.--    * Redistributions in binary form must reproduce the above copyright-      notice, this list of conditions and the following disclaimer in-      the documentation and/or other materials provided with the-      distribution.--    * Neither the name of the authors nor the names of their-      contributors may be used to endorse or promote products derived-      from this software without specific prior written permission.--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Setup.hs view
@@ -1,3 +1,5 @@ #!/usr/bin/env runhaskell+ import Distribution.Simple+ main = defaultMain
hsSqlite3.cabal view
@@ -1,17 +1,45 @@-name: hsSqlite3 cabal-version: >= 1.2.3-version: 0.0.6-build-type: Simple-synopsis: Database package using sqlite3.-author: Evgeny Jukov-maintainer: Maurício C. Antunes <mauricio.antunes@gmail.com>-stability: experimental, not usable yet-homepage: http://bitbucket.org/mauricio/hssqlite3-license: BSD3-license-file: LICENSE-category: database-library-  hs-source-dirs: src-  build-depends: base, bindings-sqlite3, utf8-string-  exposed-modules:-    Database.HsSqlite3+Name: hsSqlite3+Version: 0.1+License: LGPL+Maintainer: Evgeny Jukov <masloed@gmail.com>+Author: Evgeny Jukov+Stability: Alpha+Copyright: Copyright (c) 2007 Evgeny Jukov+license-file: COPYRIGHT+Synopsis: Sqlite3 bindings+description: Bindings for Sqlite3+Category: Database+Build-Type: Simple+Data-Files: src/hs_sqlite3_test.hs+Data-Files: src/hs_sqlite3_test.sql+Library+  Hs-Source-Dirs: src+  Extensions:+    RankNTypes+    FlexibleContexts+    DeriveDataTypeable+    GADTs+    EmptyDataDecls+    FlexibleInstances+  Exposed-Modules: +    Database.Sqlite3,+    Database.Sqlite3.Middle+  Build-Depends:+    base >=3 && <5,+    utf8-string >=0.3.5 && <0.3.6,+    mtl >=1.1 && <1.2,+    bindings-sqlite3 >=1.0 && <1.1,+    bytestring >=0.9 && <1.0+-- Executable hs_sqlite3_test+--   Main-Is: hs_sqlite3_test.hs+--   HS-Source-Dirs: src+--   Extensions:+--     RankNTypes+--     FlexibleContexts+--     DeriveDataTypeable+--     GADTs+--     EmptyDataDecls+--     FlexibleInstances+--     PatternSignatures+--     TypeOperators
− src/Database/HsSqlite3.hs
@@ -1,579 +0,0 @@--module Database.HsSqlite3- ( module Database.Sqlite3.Low- , Val ( IntV, Int64V, DoubleV, TextV, BlobV, NullV )- , fetch- , bind- , row- , test- , sql- ) where--import Data.Char-import Control.Monad-import Data.Int-import Database.Sqlite3.Low-import qualified Data.ByteString as B-import Control.Arrow-import Data.Typeable--import Control.Monad.Trans-import Control.Monad.Error-import Control.Monad.State.Lazy--import Data.Monoid--import Data.State hiding (fetch)--import qualified Codec.Binary.UTF8.String as UTF8------class ValID a where- valID  :: a -> Int--class ValFetch a where- valFetch :: (Int,Int) -> DbIO a--class ValBind a where- valBind :: (Int,a) -> DbIO ()--class ValID a => ValCast a b where- valCast :: a -> b--data Val- = IntV    Int- | Int64V  Int64- | DoubleV Double- | TextV   String- | BlobV   B.ByteString- | NullV- deriving Show--instance ValID Val where- valID (IntV    _) = 1- valID (Int64V  _) = 1- valID (DoubleV _) = 2- valID (TextV   _) = 3- valID (BlobV   _) = 4- valID  NullV      = 5--instance ValFetch Val where- valFetch (t,n) = do-  case t of-   1 -> liftM IntV    $ column_int n-   2 -> liftM DoubleV $ column_double n-   3 -> liftM TextV   $ column_text n-   4 -> liftM BlobV   $ column_blob n-   5 -> return NullV--instance ValBind Val where- valBind (t,v) = do-  case v of-   IntV a -> bind_int (t,a)-   TextV a -> bind_text (t,a)--instance ValCast Val Int where- valCast (IntV a) = a--instance ValCast Val Double where- valCast (DoubleV a) = a--instance ValCast Val String where- valCast (TextV a) = a--instance ValCast Val B.ByteString where- valCast (BlobV a) = a--instance ValCast Val () where- valCast NullV = ()--instance ValID Int          where valID _ = 1-instance ValID Double       where valID _ = 2-instance ValID String       where valID _ = 3-instance ValID B.ByteString where valID _ = 4-instance ValID ()           where valID _ = 5--reqType :: Int -> (Int -> DbIO a) -> (Int,Int) -> DbIO a-reqType t' a (t,v) =  do- errIf (t'/=t) "ValFetch"- a v--instance ValFetch Int where- valFetch = reqType 1 column_int--instance ValFetch Double where- valFetch = reqType 2 column_double--instance ValFetch String where- valFetch = reqType 3 column_text--instance ValFetch B.ByteString where- valFetch = reqType 4 column_blob--instance ValFetch () where- valFetch = reqType 5 (\_ -> return ())--instance ValBind Int where- valBind = bind_int--instance ValBind String where- valBind = bind_text--instance ValCast Int Val where- valCast a = IntV a--instance ValCast Double Val where- valCast a = DoubleV a--instance ValCast String Val where- valCast a = TextV a--instance ValCast B.ByteString Val where- valCast a = BlobV a--instance ValCast () Val where- valCast a = NullV------fetch :: ValFetch a => String -> DbIO [[a]]-fetch sql = do- liftIO $ putStr $ UTF8.encodeString $ sql++"\n"- prepare sql- stat <- step- case stat of-  True -> finalize >> return []-  False -> do-   cn <- column_count-   ty <- mapM column_type [0..cn-1]-   let ft = mapM valFetch (zip ty [0..])-   x <- ft-   xs <- fetchRow ft-   finalize-   return (x:xs)- where-  fetchRow ft = do-   end <- step-   case end of-    True -> return []-    False -> do-     x <- ft-     xs <- fetchRow ft-     return (x:xs)--sql :: String -> DbIO ()-sql sql = do- liftIO $ putStr $ UTF8.encodeString $ sql++"\n"- prepare sql- step- finalize--bind :: String -> [[Val]] -> DbIO ()-bind sql tab = do- liftIO $ putStr $ UTF8.encodeString $ sql++"\n"- debug tab- prepare sql- mapM_ (\row -> mapM_ (\(v,n) -> valBind (n,v)) (zip row [1..]) >> step >> reset) tab- finalize--fetchOne' :: ValFetch a => String -> Int -> DbIO [[a]]-fetchOne' sql num = fetch sql'- where sql' = concat [sql," LIMIT 1 OFFSET ", show num]--row :: ValFetch a => String -> Int -> DbIO [a]-row sql num = liftM head $ fetchOne' sql num--test :: String -> DbIO Bool-test sql = do- tab :: [[Val]] <- fetchOne' sql 0- case length tab of-  1 -> return True-  _ -> return False----Patch from Evgeny:--Utilization of types-For fetch-> tab :: [Nil :. Int :. Int :. Double] <- fetch "SELECT * FROM test01"->  liftIO $ mapM print tab--And for bind-> bind "INSERT INTO test01 VALUES(?,?,?)" $->  replicate 7 $->    Nil :. (1::Int) :. (2::Int) :. (3.0::Double)--This is stack with different types-> Nil :. (1::Int) :. (2::Int) :. (3.0::Double)--Definition of stack-> data Stack a where->    Nil  :: Stack ()->    (:.) :: Stack a -> b -> Stack (Stack a, b)--This is class for new kinds of values.-"T" means used in type stack ... type manipulations ...-> class Cell a where->   bindT   :: Int -> a -> Db ()->   columnT :: Int -> Db a->   idT     :: a -> Int--> instance Cell Int where->   idT _    = 1->   columnT  = columnInt->   bindT    = bindInt--> instance Cell Double where->  idT _    = 2->  columnT  = columnDouble->  bindT    = bindDouble--Equality test of derived types and database types-> fetchBody derived = do->  cn <- columnCount->  dbTypes <- mapM columnType $ enumFromThenTo (cn-1) (cn-2) 0->  case dbTypes == derived of-   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->   False -> fail "different database and haskell types"->   True  -> return ()->  x  <- columnStack->  xs <- fetchTail->  finalize->  return (x:xs)--Middle level:--Abstract away from state and errors-> class DbError e where->  makeErr :: CInt -> e->  castErr :: e -> Maybe CInt--> class MonadIO m => MonadDb m where->  getDb     :: m (Ptr L.Sqlite3)->  putDb     :: Ptr L.Sqlite3 -> m ()->  cleanDb   :: m ()->  isDbReady :: m Bool->  getSt     :: m (Ptr L.Stmt)->  putSt     :: Ptr L.Stmt -> m ()->  cleanSt   :: m ()->  isStReady :: m Bool--Simple instance for MonadDb (in Sqlite3.hs)-> data SimpleState = SimpleState-> { database  :: Maybe (Ptr L.Sqlite3)-> , statement :: Maybe (Ptr L.Stmt ) }-> ...-> instance MonadDb (StateT SimpleState (ErrorT (Either CInt String) IO)) where-- > getDb = get >>= maybe (fail "Empty database")  return . database- > getSt = get >>= maybe (fail "Empty statement") return . statement-- > putDb x = modify $ \a -> a { database  = Just x }- > putSt x = modify $ \a -> a { statement = Just x }-- > cleanDb = modify $ \a -> a { database  = Nothing }- > cleanSt = modify $ \a -> a { statement = Nothing }-- > isDbReady = get >>= return . maybe False (const True) . database- > isStReady = get >>= return . maybe False (const True) . statement-------type Void = Word8--foreign import ccall unsafe "sqlite3_open" c_open- :: CString -> Ptr (Ptr Void) -> IO Int--foreign import ccall unsafe "sqlite3_close" c_close- :: Ptr Void -> IO Int--foreign import ccall unsafe "sqlite3_errmsg" c_errmsg- :: Ptr Void -> IO CString--foreign import ccall unsafe "sqlite3_prepare_v2" c_prepare- :: Ptr Void -> CString -> Int -> Ptr (Ptr Void) -> Ptr CString -> IO Int--foreign import ccall unsafe "sqlite3_finalize" c_finalize- :: Ptr Void -> IO Int--foreign import ccall unsafe "sqlite3_reset" c_reset- :: Ptr Void -> IO Int--foreign import ccall unsafe "sqlite3_bind_int" c_bind_int- :: Ptr Void -> Int -> Int -> IO Int--foreign import ccall unsafe "sqlite3_bind_text" c_bind_text- :: Ptr Void -> Int -> CString -> Int -> Int -> IO Int--foreign import ccall unsafe "sqlite3_step" c_step- :: Ptr Void -> IO Int--foreign import ccall unsafe "sqlite3_column_blob" c_column_blob- :: Ptr Void -> Int -> IO CString--foreign import ccall unsafe "sqlite3_column_bytes" c_column_bytes- :: Ptr Void -> Int -> IO Int--foreign import ccall unsafe "sqlite3_column_count" c_column_count- :: Ptr Void -> IO Int--foreign import ccall unsafe "sqlite3_column_int" c_column_int- :: Ptr Void -> Int -> IO Int--foreign import ccall unsafe "sqlite3_column_double" c_column_double- :: Ptr Void -> Int -> IO Double--foreign import ccall unsafe "sqlite3_column_text" c_column_text- :: Ptr Void -> Int -> IO CString--foreign import ccall unsafe "sqlite3_column_type" c_column_type- :: Ptr Void -> Int -> IO Int--type DbE a =- (Error e- ,MonadError e m- ,MonadState sg m- ,LocalState sg StateDb- ,Monad m- ) => m a--type DbIO a =- (LocalState sg StateDb- ,MonadIO m- ,MonadState sg m- ,MonadError e m- ,Error e- ,Monad m- ) => m a--type E a =- (MonadError e m- ,Error e- ) => m a--data StateDb = SD- { dbP :: Maybe (Ptr Void)- , stP :: Maybe (Ptr Void)- } deriving (Show, Typeable)--instance ZeroState StateDb where- zeroState = SD-  { dbP = Nothing-  , stP = Nothing }--setDB :: Ptr Void -> DbE ()-setDB ptr = get >>= \st@(SD { dbP = dbP }) ->- case dbP of-   Nothing -> put (st { dbP = Just ptr })-   Just _  -> err "Database is allready set"--setST :: Ptr Void -> DbE ()-setST ptr = get >>= \st@(SD { stP = stP }) ->-    case stP of-      Nothing -> put (st { stP = Just ptr })-      Just _  -> err "Statement is allready set"--isSetDB :: DbE Bool-isSetDB = get >>= \(SD { dbP = dbP }) ->-    case dbP of-      Nothing -> return False-      Just _ -> return True--getDB :: DbE (Ptr Void)-getDB = get >>= \(SD { dbP = dbP }) ->-    case dbP of-      Just a  -> return a-      Nothing -> err "Database is not set"--getST :: DbE (Ptr Void)-getST = get >>= \(SD { stP = stP }) ->-    case stP of-      Just a  -> return a-      Nothing -> err "Statement is not set"--clearDB :: DbE ()-clearDB = get >>= \st@(SD { dbP = dbP }) ->-    case dbP of-      Just _  -> put (st { dbP = Nothing })-      Nothing -> err "Database is allready clear"--clearST :: DbE ()-clearST = get >>= \st@(SD { stP = stP }) ->-    case stP of-      Just _  -> put (st { stP = Nothing })-      Nothing -> err "Statement is allready clear"------err :: String -> E x-err a = throwError $ strMsg a---errRc :: Int -> String -> DbIO ()-errRc 0 _ = return ()-errRc rc msg = do- ans <- isSetDB- case ans of-  True -> do-    ptr <- getDB-    cstr <- liftIO $ c_errmsg ptr-    reason <- liftIO $ peekCString cstr-    err $ "Foreign: "++msg++": (rc="++show rc++") "++reason-  False ->-    err $ "Foreign: "++msg++": (rc="++show rc++")"--errIf :: Bool -> String -> DbIO ()-errIf False _ = return ()-errIf True msg = do- ans <- isSetDB- case ans of-  True -> do-    ptr <- getDB-    cstr <- liftIO $ c_errmsg ptr-    reason <- liftIO $ peekCString cstr-    err $ "Foreign: "++msg++": "++reason-  False ->-    err $ "Foreign: "++msg----debug a = liftIO $ hPutStr stderr $ "DEBUG: " ++ show a ++ "\n"--debug :: Show a => a -> DbIO ()-debug a = liftIO $ hPutStr stderr ("DEBUG: " ++ show a ++ "\n")----cont :: ((a -> IO (b,s)) -> IO (b,s)) -> (a -> StateT s IO b) -> StateT s IO b---cont f g = StateT $ \st -> liftIO $ f $ \a -> (runStateT (g a)) st--fin a b = catchError a (\e -> b >> throwError e)--try a = catchError (liftM Right a) (\e -> return $ Left e)------open :: String -> DbIO ()-open path = do- pptr <- i malloc- cstr <- i$ newCString path- debug (path,cstr,pptr,"open")- rc <- i$ c_open cstr pptr- ptr <- i$ peek pptr- setDB ptr- fin (errRc rc "open") $ do-   r <- try close-   case r of-     Left _   -> clearDB-     Right () -> return ()- where i = liftIO--close :: DbIO ()-close = do- ptr <- getDB- debug (ptr,"close")- rc <- liftIO $ c_close ptr- errRc rc "close"- clearDB--prepare :: String -> DbIO ()-prepare sql = do- pptr <- i malloc- (cstr,len) <- i$ newCStringLen sql- debug (sql,cstr,len,pptr,"prepare")- ptr <- getDB- rc <- i$ c_prepare ptr cstr len pptr nullPtr- sptr <- i$ peek pptr- setST sptr- fin (errRc rc "prepare") $ do-   r <- try finalize-   case r of-     Left _ -> clearST-     Right () -> return ()- where i = liftIO--finalize :: DbIO ()-finalize = do- ptr <- getST- debug (ptr,"finalize")- rc <- liftIO $ c_finalize ptr- errRc rc "finalize"- clearST--reset :: DbIO ()-reset = do- ptr <- getST- debug (ptr,"reset")- rc <- liftIO $ c_reset ptr- errRc rc "reset"--step :: DbIO Bool-step = do- ptr <- getST- debug (ptr,"step")- rc <- liftIO $ c_step ptr- errIf (rc /= 100 && rc /= 101) $ "step: "++show rc- return (rc == 101)--bind_int :: (Int,Int) -> DbIO ()-bind_int (num,val) = do- ptr <- getST- debug (ptr,"bind_int")- rc <- liftIO $ c_bind_int ptr num val- errRc rc "bind_int"--bind_text :: (Int,String) -> DbIO ()-bind_text (num,val) = do- (cstr,len) <- liftIO $ newCStringLen val- ptr <- getST- debug (ptr,"bind_text")- rc <- liftIO $ c_bind_text ptr num cstr len (-1)- errRc rc "bind_text"--column_bytes :: Int -> DbIO Int-column_bytes num = do- ptr <- getST- debug (ptr,"column_bytes")- liftIO $ c_column_bytes ptr num--column_count :: DbIO Int-column_count = do- ptr <- getST- debug (ptr,"column_count")- liftIO $ c_column_count ptr--column_int :: Int -> DbIO Int-column_int num = do- ptr <- getST- debug (ptr,"column_int")- liftIO $ c_column_int ptr num--column_double :: Int -> DbIO Double-column_double num = do- ptr <- getST- debug (ptr,"column_double")- liftIO $ c_column_double ptr num--column_type :: Int -> DbIO Int-column_type num = do- ptr <- getST- debug (ptr,"column_type")- liftIO $ c_column_type ptr num--column_text :: Int -> DbIO String-column_text num = do- ptr <- getST- by <- column_bytes num- debug (ptr,by,"column_text")- tx <- liftIO $ c_column_text ptr num- utf <- liftIO $ peekCStringLen (tx,by)- return $ UTF8.decodeString utf--column_blob :: Int -> DbIO B.ByteString-column_blob num = do- ptr <- getST- debug (ptr,"column_blob")- by <- column_bytes num- bl <- liftIO $ c_column_blob ptr num- return $ B.packCStringLen (bl,by)
+ src/Database/Sqlite3.hs view
@@ -0,0 +1,204 @@+{-+  Copyright (C) <2007-2009> <Evgeny Jukov>+  <If you contribute to Database.Sqlite3, please add your name here.>++  This library is free software; you can redistribute it and/or+  modify it under the terms of the GNU Lesser General Public+  License as published by the Free Software Foundation; either+  version 2.1 of the License, or (at your option) any later+  version.+-}++module Database.Sqlite3+ ( sql, bind, fetch, runSimpleDb+ , Stack(..), Nil, (:.), Cell(..)+ ) where++import Foreign+import Foreign.C+import Data.Char+import Control.Monad+import Data.Int+import Bindings.Sqlite3+import qualified Data.ByteString as B+import Control.Arrow++import Control.Monad.Trans+import Control.Monad.Error+import Control.Monad.State.Lazy++import Data.Monoid+++import qualified Codec.Binary.UTF8.String as UTF8++import Database.Sqlite3.Middle++--++fstT :: Stack (a, b) -> a+fstT _ = error "fstT"++sndT :: Stack (a, b) -> b+sndT _ = error "sndT"++headT :: [a] -> a+headT _ = error "headT"++performT :: Monad m => m a -> a+performT _ = error "performT"++derivT :: (Monad m, TypesStack a)+      => ([Int] -> m [Stack a]) -> m [Stack a]+derivT f = fix $ \self -> do+  f $ typesStack $ headT $ performT self++infixl 9 :.++type Nil = Stack ()+type a :. b = Stack (a, b)++data Stack a where+  Nil  :: Stack ()+  (:.) :: Stack a -> b -> Stack (Stack a, b)++instance (Show a, Show b) => Show (Stack (a, b)) where+  show (Nil :. a) = show a+  show (a :. b) = show a ++ "," ++ show b++class Length a where+  lengthT :: Stack a -> Int++instance Length () where+  lengthT _ = 0++instance Show (Stack ()) where+  show _ = []++instance Length a => Length (Stack a, b) where+  lengthT a = lengthT (fstT a) + 1++class Cell a where+  bindT   :: Int -> a -> Db ()+  columnT :: Int -> Db a+  idT     :: a -> Int++instance TypesStack () where+  typesStack _ = []++instance (TypesStack a, Cell b) => TypesStack (Stack a, b) where+  typesStack a = idT (sndT a) : typesStack (fstT a)++class Length a => ColumnStack a where+  columnStack :: Db (Stack a)++instance ColumnStack () where+  columnStack = return Nil++instance (ColumnStack a, Cell b) => ColumnStack (Stack a, b) where+  columnStack = fix $ \self -> do+    let stack = performT self+    a <- columnStack+    b <- columnT $ lengthT stack - 1+    return (a :. b)++class Length a => BindStack a where+  bindStack :: Stack a -> Db ()++instance (BindStack a, Cell b) => BindStack (Stack a, b) where+  bindStack o@(a :. b) = do+    bindStack a+    bindT (lengthT o) b++instance BindStack () where+  bindStack _ = return ()++sql :: String -> Db ()+sql sql = do+  prepare sql+  step+  finalize++class TypesStack a where+  typesStack :: Stack a -> [Int]++--++bind :: BindStack a => String -> [Stack a] -> Db ()+bind sql tab = do+  prepare sql+  mapM (\a -> bindStack a >> step >> reset) tab+  finalize++fetch sql = do+  prepare sql+  a <- step+  if a+   then finalize >> return []+   else derivT fetchBody++fetchTail :: ColumnStack a => Db [Stack a]+fetchTail = do+  a <- step+  if a+   then return []+   else do+    x  <- columnStack+    xs <- fetchTail+    return (x:xs)++data SimpleState = SimpleState+ { database  :: Maybe (Ptr C'sqlite3)+ , statement :: Maybe (Ptr C'sqlite3_stmt ) }++type SimpleDb a =+ StateT SimpleState (ErrorT (Either CInt String) IO) a++instance Error (Either CInt String) where+  strMsg = Right++instance DbError (Either CInt a) where+  makeErr = Left+  castErr (Left a) = Just a+  castErr _ = Nothing++runSimpleDb :: SimpleDb a -> IO a+runSimpleDb a = do+  c <- runErrorT tupleM+  case c of+    (Left (Left a))  -> fail (show a)+    (Left (Right a)) -> fail a+    (Right (a,_))    -> return a+ where +  tupleM = runStateT (errorHook a) $ SimpleState Nothing Nothing++instance MonadDb (StateT SimpleState (ErrorT (Either CInt String) IO)) where+  getDb = get >>= maybe (fail "Empty database")  return . database+  getSt = get >>= maybe (fail "Empty statement") return . statement+  putDb x = modify $ \a -> a { database  = Just x }+  putSt x = modify $ \a -> a { statement = Just x }+  cleanDb = modify $ \a -> a { database  = Nothing }+  cleanSt = modify $ \a -> a { statement = Nothing }+  isDbReady = get >>= return . maybe False (const True) . database+  isStReady = get >>= return . maybe False (const True) . statement++fetchBody derived = do+  cn <- columnCount+  dbTypes <- mapM columnType $ enumFromThenTo (cn-1) (cn-2) 0+  case dbTypes == derived of+   False -> fail "different database and haskell types"+   True  -> return ()+  x  <- columnStack+  xs <- fetchTail+  finalize+  return (x:xs)++instance Cell Int where+  idT _    = 1+  columnT  = columnInt+  bindT    = bindInt++instance Cell Double where+  idT _    = 2+  columnT  = columnDouble+  bindT    = bindDouble
+ src/Database/Sqlite3/Middle.hs view
@@ -0,0 +1,154 @@+module Database.Sqlite3.Middle where++import Bindings.Sqlite3+import qualified Data.ByteString as B++import Codec.Binary.UTF8.String+import Control.Monad.Error+import Foreign.C hiding (newCString)+import Foreign.Marshal.Alloc+import Foreign.Marshal.Array+import Foreign.Ptr+import Foreign.Storable++type Db a = (DbError e, MonadError e m, MonadDb m) => m a++class DbError e where+  makeErr :: CInt -> e+  castErr :: e -> Maybe CInt++class MonadIO m => MonadDb m where+  getDb     :: m (Ptr C'sqlite3)+  putDb     :: Ptr C'sqlite3 -> m ()+  cleanDb   :: m ()+  isDbReady :: m Bool+  getSt     :: m (Ptr C'sqlite3_stmt)+  putSt     :: Ptr C'sqlite3_stmt -> m ()+  cleanSt   :: m ()+  isStReady :: m Bool++open :: String -> Db ()+open path = do+  cpath <- liftIO $ newCString path+  db'   <- liftIO $ malloc+  rc    <- liftIO $ c'sqlite3_open cpath db'+  db    <- liftIO $ peek db'+  putDb db+  liftIO $ free db'+  err rc++close :: Db ()+close = do+  db <- getDb+  rc  <- liftIO $ c'sqlite3_close db+  cleanDb+  err rc++prepare :: String -> Db ()+prepare sql = do+  cstr <- liftIO $ newCString sql+  let len = toEnum $ length sql+  st'  <- liftIO $ malloc+  db   <- getDb+  rc   <- liftIO $ c'sqlite3_prepare db cstr len st' nullPtr+  st   <- liftIO $ peek st'+  putSt st+  liftIO $ free st'+  err rc++finalize :: Db ()+finalize = do+  st <- getSt+  rc <- liftIO $ c'sqlite3_finalize st+  cleanSt+  err rc++reset :: Db ()+reset = do+  st <- getSt+  rc <- liftIO $ c'sqlite3_reset st+  err rc++step :: Db Bool+step = do+  st <- getSt+  rc <- liftIO $ c'sqlite3_step st+  case rc of+    100 -> return False+    101 -> return True+    _   -> throwError (makeErr rc)++bindInt :: Int -> Int -> Db ()+bindInt num val = do+  st <- getSt+  rc <- liftIO $ c'sqlite3_bind_int st (toEnum num) (toEnum val)+  err rc++bindDouble :: Int -> Double -> Db ()+bindDouble num val = do+  st <- getSt+  rc <- liftIO $ c'sqlite3_bind_double st (toEnum num) (realToFrac val)+  err rc++bindText :: Int -> String -> Db ()+bindText num val = do+  cstr <- liftIO $ newCString val+  let len = toEnum $ length val+  st   <- getSt+  rc   <- liftIO $ c'sqlite3_bind_text st (toEnum num) cstr len nullFunPtr+  err rc++columnBytes :: Int -> Db Int+columnBytes num = do+  st <- getSt+  cint <- liftIO $ c'sqlite3_column_bytes st (toEnum num)+  return (fromEnum cint)++columnCount :: Db Int+columnCount = do+  st <- getSt+  cint <- liftIO $ c'sqlite3_column_count st+  return (fromEnum cint)++columnInt :: Int -> Db Int+columnInt num = do+  st <- getSt+  cint <- liftIO $ c'sqlite3_column_int st (toEnum num)+  return (fromEnum cint)++columnType :: Int -> Db Int+columnType num = do+  st <- getSt+  cint <- liftIO $ c'sqlite3_column_type st (toEnum num)+  return (fromEnum cint)++columnDouble :: Int -> Db Double+columnDouble num = do+  st <- getSt+  x <- liftIO $ c'sqlite3_column_double st (toEnum num)+  return (realToFrac x)++columnBlob :: Int -> Db B.ByteString+columnBlob num = do+  st <- getSt+  by <- columnBytes num+  bl <- liftIO $ c'sqlite3_column_blob st (toEnum num)+  liftIO $ B.packCStringLen (castPtr bl,by)++errorHook x = catchError x hook where+ hook e = do+   ignore finalize+   ignore close+   throwError e++ignore x = catchError (x >> return ()) (const $ return ())++newCString :: String -> IO CString+newCString = newArray0 0 . map fromIntegral . encode++err :: CInt -> Db ()+err 0 = return ()+err x = throwError (makeErr x)+++
− src/Examples/hs_sqlite3_test.hs
@@ -1,27 +0,0 @@--- Not yet updated, and so should--- not be built (yet).--import Data.Char-import Database.Sqlite3 (Val (IntV,TextV))-import qualified Database.Sqlite3 as S-import qualified Data.ByteString as B--import Control.Monad.Trans-import Control.Monad.Error-import Control.Monad.State.Lazy-import Data.State--instance LocalState a a where- getState = id- putState a _ = a--main = do-  x <- (`runStateT` (zeroState :: S.StateDb)) $ do-    S.open "db"-    tab :: [[Val]] <- S.fetch "SELECT * FROM test_tab"-    S.bind "INSERT INTO test_tab VALUES (?,?,?)" $-       replicate 4-        [IntV 5,TextV "B test",TextV "test C test"]-    S.close-    return tab-  putStr $ "end"++ show x ++"\n"
+ src/hs_sqlite3_test.hs view
@@ -0,0 +1,20 @@+import Database.Sqlite3+import Database.Sqlite3.Middle+import Control.Monad.Trans++main = runSimpleDb $ do++  open "db"++  liftIO $ print "Start"++  tab :: [Nil :. Int :. Int :. Double] <- fetch "SELECT * FROM test01"+  liftIO $ mapM print tab++  bind "INSERT INTO test01 VALUES(?,?,?)" $+    replicate 7 $+      Nil :. (1::Int) :. (2::Int) :. (3.0::Double)++  close++  liftIO $ print "Finish"
+ src/hs_sqlite3_test.sql view
@@ -0,0 +1,9 @@+CREATE TABLE IF NOT EXISTS test01 (+ a INT NOT NULL,+ b INT NOT NULL,+ c DOUBLE NOT NULL+);++INSERT INTO test01 VALUES(1,2,3.0);+INSERT INTO test01 VALUES(2,3,4.0);+INSERT INTO test01 VALUES(3,4,5.0);