Ngugi1 / sqlite-net

Automatically exported from code.google.com/p/sqlite-net
0 stars 0 forks source link

Two enhancements - blobs and fix for enumerator #11

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,

Not sure this is the right place for this, but here are two fixes that I'm 
using.

#1 Add support for blobs. 

I've not done much testing, but adding support for byte[] mapping 
to "blob" seems to be enough to do the trick in "SqlType"

        public static string SqlType (TableMapping.Column p)
        {
            var clrType = p.ColumnType;
            if (clrType == typeof(Boolean) || clrType == typeof
(Byte) || clrType == typeof(UInt16) || clrType == typeof(SByte) || clrType 
== typeof(Int16) || clrType == typeof(Int32)) {
                return "integer";
            } else if (clrType == typeof(UInt32) || clrType == 
typeof(Int64)) {
                return "bigint";
            } else if (clrType == typeof(Single) || clrType == 
typeof(Double) || clrType == typeof(Decimal)) {
                return "float";
            } else if (clrType == typeof(String)) {
                int len = p.MaxStringLength;
                return "varchar(" + len + ")";
            } else if (clrType == typeof(DateTime)) {
                return "datetime";
            } else if (clrType==typeof(byte[])) {
                return "blob";
            } else if (clrType.IsEnum) {
                return "integer";
            } else {
                throw new NotSupportedException ("Don't 
know about " + clrType);
            }
        }

#2 Properly closing statements in enumerators

Little known fact with yield is that you can break out of a foreach.  If 
you do, then the SQLite3.Finalize never gets called, the statement is left 
open and the database locked... a bad thing.

Easy fix is to add a try/finally around the yield loop in ExecteQuery<>:

        public IEnumerable<object> ExecuteQuery (TableMapping map)
        {
            if (_conn.Trace) {
                Console.WriteLine ("Executing Query: " + 
this);
            }

            var stmt = Prepare ();

            var cols = new TableMapping.Column
[SQLite3.ColumnCount (stmt)];
            for (int i = 0; i < cols.Length; i++) {
                var name = Marshal.PtrToStringUni
(SQLite3.ColumnName16 (stmt, i));
                cols[i] = map.FindColumn (name);
            }

            // Mike Warriner - yield doesn't necessarily run through all 
permutations so added try/finally
            try
            {
                while (SQLite3.Step(stmt) == SQLite3.Result.Row)
                {
                    var obj = Activator.CreateInstance(map.MappedType);
                    map.SetConnection(obj, _conn);
                    for (int i = 0; i < cols.Length; i++)
                    {
                        if (cols[i] == null)
                            continue;
                        var val = ReadCol(stmt, i, cols[i].ColumnType);
                        cols[i].SetValue(obj, val);
                    }
                    yield return obj;
                }
            }
            finally
            {
                SQLite3.Finalize(stmt);
            }
        }

Hope you find these useful,

Mike

Original issue reported on code.google.com by MikeWarr...@gmail.com on 18 Mar 2010 at 9:11

GoogleCodeExporter commented 9 years ago
#2 seems not to be the case anymore?

What about #1? Seems not to have been applied?

Original comment by anders.rune.jensen on 12 Jul 2010 at 5:07

GoogleCodeExporter commented 9 years ago
A patch for #1 is on:
http://code.google.com/p/sqlite-net/issues/detail?id=28

Original comment by elite.da...@gmail.com on 27 Oct 2010 at 8:26

GoogleCodeExporter commented 9 years ago
#1 and 2 should now be fixed. Let us know if they're not.

Original comment by frank.al...@gmail.com on 14 Nov 2010 at 12:32