<commit_before>﻿/*
   Copyright 2014-2019 SourceGear, LLC

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using SQLitePCL;
using SQLitePCL.Ugly;

using Xunit;

namespace SQLitePCL.Tests
{

    [CollectionDefinition("Init")]
    public class InitCollection : ICollectionFixture<Init>
    {
    }

    public class Init
    {
        public Init()
        {
            //SQLitePCL.Setup.Load("c:/Windows/system32/winsqlite3.dll");
            //SQLitePCL.Setup.Load("e_sqlite3.dll");
            SQLitePCL.Batteries_V2.Init();
        }
    }

    [Collection("Init")]
    public class test_cases
    {
        [Fact]
        public void test_bind_parameter_index()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                db.exec("CREATE TABLE foo (x int, v int, t text, d real, b blob, q blob);");
                using (sqlite3_stmt stmt = db.prepare("INSERT INTO foo (x,v,t,d,b,q) VALUES (:x,:v,:t,:d,:b,:q)"))
                {
                    Assert.True(stmt.stmt_readonly() == 0);

                    Assert.Equal(6, stmt.bind_parameter_count());

                    Assert.Equal(0, stmt.bind_parameter_index(":m"));

                    Assert.Equal(1, stmt.bind_parameter_index(":x"));
                    Assert.Equal(2, stmt.bind_parameter_index(":v"));
                    Assert.Equal(3, stmt.bind_parameter_index(":t"));
                    Assert.Equal(4, stmt.bind_parameter_index(":d"));
                    Assert.Equal(5, stmt.bind_parameter_index(":b"));
                    Assert.Equal(6, stmt.bind_parameter_index(":q"));

                    Assert.Equal(":x", stmt.bind_parameter_name(1));
                    Assert.Equal(":v", stmt.bind_parameter_name(2));
                    Assert.Equal(":t", stmt.bind_parameter_name(3));
                    Assert.Equal(":d", stmt.bind_parameter_name(4));
                    Assert.Equal(":b", stmt.bind_parameter_name(5));
                    Assert.Equal(":q", stmt.bind_parameter_name(6));
                }
            }
        }

        [Fact]
        public void test_blob_reopen()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len_1 = 42;
                const int len_2 = 87;

                db.exec("CREATE TABLE foo (b blob);");
                db.exec("INSERT INTO foo (b) VALUES (randomblob(?))", len_1);
                long rowid_1 = db.last_insert_rowid();
                db.exec("INSERT INTO foo (b) VALUES (randomblob(?))", len_2);
                long rowid_2 = db.last_insert_rowid();

                byte[] blob_1 = db.query_scalar<byte[]>("SELECT b FROM foo WHERE rowid=?;", rowid_1);
                Assert.Equal(blob_1.Length, len_1);

                byte[] blob_2 = db.query_scalar<byte[]>("SELECT b FROM foo WHERE rowid=?;", rowid_2);
                Assert.Equal(blob_2.Length, len_2);

                Func<sqlite3_blob, byte[], bool> Check =
                (bh, ba) =>
                {
                    int len = bh.bytes();
                    if (len != ba.Length)
                    {
                        return false;
                    }

                    byte[] buf = new byte[len];

                    bh.read(buf, 0);
                    for (int i = 0; i < len; i++)
                    {
                        if (ba[i] != buf[i])
                        {
                            return false;
                        }
                    }
                    return true;
                };

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid_1, 0))
                {
                    Assert.True(Check(bh, blob_1));
                    Assert.False(Check(bh, blob_2));

                    bh.reopen(rowid_2);

                    Assert.False(Check(bh, blob_1));
                    Assert.True(Check(bh, blob_2));
                }
            }

        }

        [Fact]
        public void test_blob_read()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len = 100;

                db.exec("CREATE TABLE foo (b blob);");
                db.exec("INSERT INTO foo (b) VALUES (randomblob(?))", len);
                long rowid = db.last_insert_rowid();

                byte[] blob = db.query_scalar<byte[]>("SELECT b FROM foo;");
                Assert.Equal(blob.Length, len);

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid, 0))
                {
                    int len2 = bh.bytes();
                    Assert.Equal(len, len2);

                    int passes = 10;

                    Assert.Equal(0, len % passes);

                    int sublen = len / passes;
                    byte[] buf = new byte[sublen];

                    for (int q = 0; q < passes; q++)
                    {
                        bh.read(buf, q * sublen);

                        for (int i = 0; i < sublen; i++)
                        {
                            Assert.Equal(blob[q * sublen + i], buf[i]);
                        }
                    }
                }
            }

        }

        [Fact]
        public void test_blob_read_with_byte_array_offset()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len = 100;

                db.exec("CREATE TABLE foo (b blob);");
                db.exec("INSERT INTO foo (b) VALUES (zeroblob(?))", len);
                long rowid = db.last_insert_rowid();

                byte[] blob = db.query_scalar<byte[]>("SELECT b FROM foo;");
                Assert.Equal(blob.Length, len);

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid, 0))
                {
                    int len2 = bh.bytes();
                    Assert.Equal(len, len2);

                    byte[] blob2 = new byte[len];
                    for (int i = 0; i < len; i++)
                    {
                        blob2[i] = 73;
                    }

                    var sp = new Span<byte>(blob2, 40, 20);
                    bh.read(sp, 40);

                    for (int i = 0; i < 40; i++)
                    {
                        Assert.Equal(73, blob2[i]);
                    }

                    for (int i = 40; i < 60; i++)
                    {
                        Assert.Equal(0, blob2[i]);
                    }

                    for (int i = 60; i < 100; i++)
                    {
                        Assert.Equal(73, blob2[i]);
                    }
                }
            }

        }

        [Fact]
        public void test_blob_write_with_byte_array_offset()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len = 100;

                db.exec("CREATE TABLE foo (b blob);");
                db.exec("INSERT INTO foo (b) VALUES (zeroblob(?))", len);
                long rowid = db.last_insert_rowid();

                byte[] blob = db.query_scalar<byte[]>("SELECT b FROM foo;");
                Assert.Equal(blob.Length, len);

                for (int i = 0; i < 100; i++)
                {
                    Assert.Equal(0, blob[i]);
                }

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid, 1))
                {
                    int len2 = bh.bytes();
                    Assert.Equal(len, len2);

                    byte[] blob2 = new byte[len];
                    for (int i = 0; i < 100; i++)
                    {
                        blob2[i] = 73;
                    }

                    var sp = new ReadOnlySpan<byte>(blob2, 40, 20);
                    bh.write(sp, 50);
                }

                byte[] blob3 = db.query_scalar<byte[]>("SELECT b FROM foo;");
                Assert.Equal(blob3.Length, len);

                for (int i = 0; i < 50; i++)
                {
                    Assert.Equal(0, blob3[i]);
                }

                for (int i = 50; i < 70; i++)
                {
                    Assert.Equal(73, blob3[i]);
                }

                for (int i = 70; i < 100; i++)
                {
                    Assert.Equal(0, blob3[i]);
                }

            }

        }

        [Fact]
        public void test_blob_write()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len = 100;

                db.exec("CREATE TABLE foo (b blob);");
                using (sqlite3_stmt stmt = db.prepare("INSERT INTO foo (b) VALUES (?)"))
                {
                    stmt.bind_zeroblob(1, len);
                    stmt.step();
                }

                long rowid = db.last_insert_rowid();

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid, 1))
                {
                    int len2 = bh.bytes();
                    Assert.Equal(len, len2);

                    int passes = 10;

                    Assert.Equal(0, len % passes);

                    int sublen = len / passes;
                    byte[] buf = new byte[sublen];
                    for (int i = 0; i < sublen; i++)
                    {
                        buf[i] = (byte)(i % 256);
                    }

                    for (int q = 0; q < passes; q++)
                    {
                        bh.write(buf, q * sublen);
                    }
                }
            }
        }

        [Fact]
        public void test_db_readonly()
        {
            using (sqlite3 db = ugly.open_v2(":memory:", raw.SQLITE_OPEN_READONLY, null))
            {
                int result = raw.sqlite3_db_readonly(db, "main");
                Assert.True(result > 0);
            }

            using (sqlite3 db = ugly.open(":memory:"))
            {
                int result = raw.sqlite3_db_readonly(db, "main");
                Assert.Equal(0, result);
            }
        }

        [Fact]
        public void test_get_autocommit()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                Assert.Equal(1, db.get_autocommit());
                db.exec("BEGIN TRANSACTION;");
                Assert.True(db.get_autocommit() == 0);
            }
        }

        [Fact]<commit_msg>add test to manually close a blob<commit_after>﻿/*
   Copyright 2014-2019 SourceGear, LLC

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using SQLitePCL;
using SQLitePCL.Ugly;

using Xunit;

namespace SQLitePCL.Tests
{

    [CollectionDefinition("Init")]
    public class InitCollection : ICollectionFixture<Init>
    {
    }

    public class Init
    {
        public Init()
        {
            //SQLitePCL.Setup.Load("c:/Windows/system32/winsqlite3.dll");
            //SQLitePCL.Setup.Load("e_sqlite3.dll");
            SQLitePCL.Batteries_V2.Init();
        }
    }

    [Collection("Init")]
    public class test_cases
    {
        [Fact]
        public void test_bind_parameter_index()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                db.exec("CREATE TABLE foo (x int, v int, t text, d real, b blob, q blob);");
                using (sqlite3_stmt stmt = db.prepare("INSERT INTO foo (x,v,t,d,b,q) VALUES (:x,:v,:t,:d,:b,:q)"))
                {
                    Assert.True(stmt.stmt_readonly() == 0);

                    Assert.Equal(6, stmt.bind_parameter_count());

                    Assert.Equal(0, stmt.bind_parameter_index(":m"));

                    Assert.Equal(1, stmt.bind_parameter_index(":x"));
                    Assert.Equal(2, stmt.bind_parameter_index(":v"));
                    Assert.Equal(3, stmt.bind_parameter_index(":t"));
                    Assert.Equal(4, stmt.bind_parameter_index(":d"));
                    Assert.Equal(5, stmt.bind_parameter_index(":b"));
                    Assert.Equal(6, stmt.bind_parameter_index(":q"));

                    Assert.Equal(":x", stmt.bind_parameter_name(1));
                    Assert.Equal(":v", stmt.bind_parameter_name(2));
                    Assert.Equal(":t", stmt.bind_parameter_name(3));
                    Assert.Equal(":d", stmt.bind_parameter_name(4));
                    Assert.Equal(":b", stmt.bind_parameter_name(5));
                    Assert.Equal(":q", stmt.bind_parameter_name(6));
                }
            }
        }

        [Fact]
        public void test_blob_reopen()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len_1 = 42;
                const int len_2 = 87;

                db.exec("CREATE TABLE foo (b blob);");
                db.exec("INSERT INTO foo (b) VALUES (randomblob(?))", len_1);
                long rowid_1 = db.last_insert_rowid();
                db.exec("INSERT INTO foo (b) VALUES (randomblob(?))", len_2);
                long rowid_2 = db.last_insert_rowid();

                byte[] blob_1 = db.query_scalar<byte[]>("SELECT b FROM foo WHERE rowid=?;", rowid_1);
                Assert.Equal(blob_1.Length, len_1);

                byte[] blob_2 = db.query_scalar<byte[]>("SELECT b FROM foo WHERE rowid=?;", rowid_2);
                Assert.Equal(blob_2.Length, len_2);

                Func<sqlite3_blob, byte[], bool> Check =
                (bh, ba) =>
                {
                    int len = bh.bytes();
                    if (len != ba.Length)
                    {
                        return false;
                    }

                    byte[] buf = new byte[len];

                    bh.read(buf, 0);
                    for (int i = 0; i < len; i++)
                    {
                        if (ba[i] != buf[i])
                        {
                            return false;
                        }
                    }
                    return true;
                };

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid_1, 0))
                {
                    Assert.True(Check(bh, blob_1));
                    Assert.False(Check(bh, blob_2));

                    bh.reopen(rowid_2);

                    Assert.False(Check(bh, blob_1));
                    Assert.True(Check(bh, blob_2));
                }
            }

        }

        [Fact]
        public void test_blob_read()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len = 100;

                db.exec("CREATE TABLE foo (b blob);");
                db.exec("INSERT INTO foo (b) VALUES (randomblob(?))", len);
                long rowid = db.last_insert_rowid();

                byte[] blob = db.query_scalar<byte[]>("SELECT b FROM foo;");
                Assert.Equal(blob.Length, len);

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid, 0))
                {
                    int len2 = bh.bytes();
                    Assert.Equal(len, len2);

                    int passes = 10;

                    Assert.Equal(0, len % passes);

                    int sublen = len / passes;
                    byte[] buf = new byte[sublen];

                    for (int q = 0; q < passes; q++)
                    {
                        bh.read(buf, q * sublen);

                        for (int i = 0; i < sublen; i++)
                        {
                            Assert.Equal(blob[q * sublen + i], buf[i]);
                        }
                    }
                }
            }

        }

        [Fact]
        public void test_blob_read_with_byte_array_offset()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len = 100;

                db.exec("CREATE TABLE foo (b blob);");
                db.exec("INSERT INTO foo (b) VALUES (zeroblob(?))", len);
                long rowid = db.last_insert_rowid();

                byte[] blob = db.query_scalar<byte[]>("SELECT b FROM foo;");
                Assert.Equal(blob.Length, len);

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid, 0))
                {
                    int len2 = bh.bytes();
                    Assert.Equal(len, len2);

                    byte[] blob2 = new byte[len];
                    for (int i = 0; i < len; i++)
                    {
                        blob2[i] = 73;
                    }

                    var sp = new Span<byte>(blob2, 40, 20);
                    bh.read(sp, 40);

                    for (int i = 0; i < 40; i++)
                    {
                        Assert.Equal(73, blob2[i]);
                    }

                    for (int i = 40; i < 60; i++)
                    {
                        Assert.Equal(0, blob2[i]);
                    }

                    for (int i = 60; i < 100; i++)
                    {
                        Assert.Equal(73, blob2[i]);
                    }
                }
            }

        }

        [Fact]
        public void test_blob_write_with_byte_array_offset()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len = 100;

                db.exec("CREATE TABLE foo (b blob);");
                db.exec("INSERT INTO foo (b) VALUES (zeroblob(?))", len);
                long rowid = db.last_insert_rowid();

                byte[] blob = db.query_scalar<byte[]>("SELECT b FROM foo;");
                Assert.Equal(blob.Length, len);

                for (int i = 0; i < 100; i++)
                {
                    Assert.Equal(0, blob[i]);
                }

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid, 1))
                {
                    int len2 = bh.bytes();
                    Assert.Equal(len, len2);

                    byte[] blob2 = new byte[len];
                    for (int i = 0; i < 100; i++)
                    {
                        blob2[i] = 73;
                    }

                    var sp = new ReadOnlySpan<byte>(blob2, 40, 20);
                    bh.write(sp, 50);
                }

                byte[] blob3 = db.query_scalar<byte[]>("SELECT b FROM foo;");
                Assert.Equal(blob3.Length, len);

                for (int i = 0; i < 50; i++)
                {
                    Assert.Equal(0, blob3[i]);
                }

                for (int i = 50; i < 70; i++)
                {
                    Assert.Equal(73, blob3[i]);
                }

                for (int i = 70; i < 100; i++)
                {
                    Assert.Equal(0, blob3[i]);
                }

            }

        }

        [Fact]
        public void test_blob_write()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len = 100;

                db.exec("CREATE TABLE foo (b blob);");
                using (sqlite3_stmt stmt = db.prepare("INSERT INTO foo (b) VALUES (?)"))
                {
                    stmt.bind_zeroblob(1, len);
                    stmt.step();
                }

                long rowid = db.last_insert_rowid();

                using (sqlite3_blob bh = db.blob_open("main", "foo", "b", rowid, 1))
                {
                    int len2 = bh.bytes();
                    Assert.Equal(len, len2);

                    int passes = 10;

                    Assert.Equal(0, len % passes);

                    int sublen = len / passes;
                    byte[] buf = new byte[sublen];
                    for (int i = 0; i < sublen; i++)
                    {
                        buf[i] = (byte)(i % 256);
                    }

                    for (int q = 0; q < passes; q++)
                    {
                        bh.write(buf, q * sublen);
                    }
                }
            }
        }

        [Fact]
        public void test_blob_close()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                const int len = 100;

                db.exec("CREATE TABLE foo (b blob);");
                using (sqlite3_stmt stmt = db.prepare("INSERT INTO foo (b) VALUES (?)"))
                {
                    stmt.bind_zeroblob(1, len);
                    stmt.step();
                }

                long rowid = db.last_insert_rowid();

                var rc = raw.sqlite3_blob_open(db, "main", "foo", "b", rowid, 1, out var bh);
                Assert.Equal(0, rc);
                Assert.NotNull(bh);

                rc = raw.sqlite3_blob_close(bh);
                Assert.Equal(0, rc);

                bh.Dispose();
            }
        }

        [Fact]
        public void test_db_readonly()
        {
            using (sqlite3 db = ugly.open_v2(":memory:", raw.SQLITE_OPEN_READONLY, null))
            {
                int result = raw.sqlite3_db_readonly(db, "main");
                Assert.True(result > 0);
            }

            using (sqlite3 db = ugly.open(":memory:"))
            {
                int result = raw.sqlite3_db_readonly(db, "main");
                Assert.Equal(0, result);
            }
        }

        [Fact]
        public void test_get_autocommit()
        {
            using (sqlite3 db = ugly.open(":memory:"))
            {
                Assert.Equal(1, db.get_autocommit());
                db.exec("BEGIN TRANSACTION;");
                Assert.True(db.get_autocommit() == 0);
            }
        }

        [Fact]
{'fraction_non_alphanumeric': 0.12219385509287789, 'fraction_numerical': 0.017563165771634828, 'mean_word_length': 1.118124184225247, 'pattern_counts': {'":': 45, '<': 51, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5799723', 'n_tokens_mistral': 6884, 'n_tokens_neox': 6126, 'n_words': 1465}