示例#1
0
 public void CanCommitTransaction()
 {
     using (var sw = new MsSqlWorker(ConnectionString))
         using (var tran = sw.TransactionBegin())
         {
             var insertsCount = sw.Exec(
                 command: @"insert into numbers values (@number, @square, @sqrt, @is_prime, @as_text)",
                 parameters: new SwParameters
             {
                 { "number", 4 },
                 { "square", 16L },
                 { "sqrt", 2.0 },
                 { "is_prime", false },
                 { "as_text", "four" },
             },
                 transaction: tran);
             Assert.AreEqual(1, insertsCount);
             tran.Commit();
         }
     using (var sw = new MsSqlWorker(ConnectionString))
     {
         Assert.AreEqual(
             expected: (4, 16L, 2.0, false, "four"),
             actual: sw.Query("select * from numbers where number = 4", dr => ((int)dr[0], (long)dr[1], (double)dr[2], (bool)dr[3], (string)dr[4])).Single());
     }
 }
示例#2
0
 public void AddDevicePerson(long phone, string device_id)
 {
     try
     {
         using (var connection = new MsSqlWorker(GetConnection()))
         {
             connection.Exec(
                 @"
                               insert into PersonDevice (phone, device_id)
                               values(@phone, @device_id)
                             ", parameters: new SwParameters
             {
                 { "phone", phone },
                 { "device_id", device_id }
             });
             if (_cachePhonePerson.Count != 0)
             {
                 _cacheDevicePerson[device_id] = _cachePhonePerson[phone];
             }
         }
     }
     catch (Exception e)
     {
         HandleExceptionSql(e);
         throw;
     }
 }
示例#3
0
 public void TransactionRolledBackIfNotCommitted()
 {
     using (var sw = new MsSqlWorker(ConnectionString))
         using (var tran = sw.TransactionBegin())
         {
             var insertsCount = sw.Exec(
                 command: @"insert into numbers values (@number, @square, @sqrt, @is_prime, @as_text)",
                 parameters: new SwParameters
             {
                 { "number", 100500 },
                 { "square", -1 },
                 { "sqrt", 0.0 },
                 { "is_prime", false },
                 { "as_text", (string)null },
             },
                 transaction: tran);
             Assert.AreEqual(1, insertsCount);
         }
     using (var sw = new MsSqlWorker(ConnectionString))
     {
         Assert.AreEqual(
             expected: 0,
             actual: sw.Query("select COUNT(*) from numbers where number = 100500", dr => (int)dr[0]).Single());
     }
 }
示例#4
0
        public void CanExecWithSwParameters()
        {
            using (var sw = new MsSqlWorker(ConnectionString))
            {
                var insertsCount = sw.Exec(
                    command: @"insert into numbers values (@number, @square, @sqrt, @is_prime, @as_text)",
                    parameters: new SwParameters {
                    { "number", 3 },
                    { "square", 9, System.Data.DbType.Int64 },
                    { "sqrt", Math.Sqrt(3), System.Data.DbType.Double, System.Data.ParameterDirection.Input },
                    { "is_prime", true },
                    { "as_text", "three" },
                });
                Assert.AreEqual(1, insertsCount);

                var inserted = sw.Query(
                    command: @"select * from numbers where number = 3",
                    transformFunction: dr => (
                        number: (int)dr[0],
                        square: (long)dr[1],
                        sqrt: (double)dr[2],
                        is_prime: (bool)dr[3],
                        as_text: dr.GetNullableString(4)
                        ))
                               .Single();
                Assert.AreEqual((3, 9L, 1.7320508075688773, true, "three"), inserted);
            }
        }
示例#5
0
        public void CanExecWithParametersDictionary()
        {
            using (var sw = new MsSqlWorker(ConnectionString))
            {
                var insertsCount = sw.Exec(
                    command: @"insert into numbers values (@number, @square, @sqrt, @is_prime, @as_text)",
                    parameters: new Dictionary <string, object> {
                    { "number", 2 },
                    { "square", 4L },
                    { "sqrt", Math.Sqrt(2) },
                    { "is_prime", true },
                    { "as_text", "two" },
                });
                Assert.AreEqual(1, insertsCount);

                var inserted = sw.Query(
                    command: @"select * from numbers where number = 2",
                    transformFunction: dr => (
                        number: (int)dr[0],
                        square: (long)dr[1],
                        sqrt: (double)dr[2],
                        is_prime: (bool)dr[3],
                        as_text: dr.GetNullableString(4)
                        ))
                               .Single();
                Assert.AreEqual((2, 4L, 1.4142135623730951, true, "two"), inserted);
            }
        }
示例#6
0
        public void CanExecWithParametersArray()
        {
            using (var sw = new MsSqlWorker(ConnectionString))
            {
                var insertsCount = sw.Exec(
                    command: @"insert into numbers values (@number, @square, @sqrt, @is_prime, @as_text)",
                    parameters: new []
                {
                    new SqlParameter("number", 1),
                    new SqlParameter("square", 1L),
                    new SqlParameter("sqrt", 1.0),
                    new SqlParameter("is_prime", false),
                    new SqlParameter("as_text", "one"),
                });
                Assert.AreEqual(1, insertsCount);

                var inserted = sw.Query(
                    command: @"select * from numbers where number = 1",
                    transformFunction: dr => (
                        number: (int)dr[0],
                        square: (long)dr[1],
                        sqrt: (double)dr[2],
                        is_prime: (bool)dr[3],
                        as_text: dr.GetNullableString(4)
                        ))
                               .Single();
                Assert.AreEqual((1, 1L, 1.0, false, "one"), inserted);
            }
        }
示例#7
0
        public async Task CheckOutputParameters()
        {
            await using var sw = new MsSqlWorker(ConnectionString);

            MsSqlWorker.DbParametersConstructor args = new SwParameters
            {
                { "primePosition", 1 },
                { "number", 0, System.Data.DbType.Int32, System.Data.ParameterDirection.Output },
                { "square", 0L, DbType.Int64, ParameterDirection.Output },
                { "sqrt", 0.0, DbType.Double, ParameterDirection.Output },
                { "result", 0, DbType.Int32, ParameterDirection.ReturnValue },
            };

            await sw.ExecAsync("GetPrimeNumber", args, commandType : System.Data.CommandType.StoredProcedure);

            Assert.AreEqual((int)args[1].Value, 2);
            Assert.AreEqual((int)args[4].Value, 1);

            args[0].Value = 2;
            await sw.ExecAsync("GetPrimeNumber", args, commandType : System.Data.CommandType.StoredProcedure);

            Assert.AreEqual((int)args["number"].Value, 3);
            Assert.AreEqual((int)args["result"].Value, 1);

            Func <int, int, int, Task> assert = async(position, number, result) =>
            {
                args["primePosition"].Value = position;
                await sw.ExecAsync("GetPrimeNumber", args, commandType : System.Data.CommandType.StoredProcedure);

                Assert.AreEqual((int)args["number"].Value, number);
                Assert.AreEqual((int)args["result"].Value, result);
            };

            await assert(3, 5, 1);
            await assert(4, 7, 1);
            await assert(5, 11, 1);
            await assert(6, 13, 1);
            await assert(7, 17, 1);
            await assert(8, 19, 1);
            await assert(9, 23, 1);
            await assert(10, 29, 1);
            await assert(11, 31, 1);

            args[0].Value = 100500;
            await sw.ExecAsync("GetPrimeNumber", args, commandType : System.Data.CommandType.StoredProcedure);

            Assert.AreEqual((int)args["result"].Value, 0);
        }
示例#8
0
        public void CanBulkInsert()
        {
            using (var sw = new MsSqlWorker(ConnectionString))
            {
                void bulkInsertAndCheck(int start, int length, int chunkSize)
                {
                    using (var tran = sw.SqlTransactionBegin())
                    {
                        var rangeToInsert = Enumerable
                                            .Range(start, length)
                                            .Select(i => new { number = i, square = (long)i * i, sqrt = Math.Sqrt(i), is_prime = _primes.Contains(i), as_text = (string)null })
                                            .ToArray();

                        sw.BulkCopyWithReflection(
                            source: rangeToInsert,
                            targetTableName: "numbers",
                            transaction: tran);
                        tran.Commit();

                        CollectionAssert.AreEquivalent(
                            expected: rangeToInsert,
                            actual: sw.Query(
                                "select * from numbers where number >= @min_number",
                                dr => new { number = (int)dr[0], square = (long)dr[1], sqrt = (double)dr[2], is_prime = (bool)dr[3], as_text = dr.GetNullableString(4) },
                                parameters: new SwParameters {
                            { "min_number", start }
                        })
                            .ToArray());
                    }
                }

                bulkInsertAndCheck(5, 3, 1);
                bulkInsertAndCheck(8, 7, 2);
                bulkInsertAndCheck(15, 10, 3);
                bulkInsertAndCheck(25, 11, 3);
                bulkInsertAndCheck(36, 16, 5);
                bulkInsertAndCheck(52, 18, 5);
                bulkInsertAndCheck(70, 20, 5);
                bulkInsertAndCheck(90, 20, 7);
                bulkInsertAndCheck(110, 0, 11);
                bulkInsertAndCheck(110, 10, 11);
                bulkInsertAndCheck(120, 11, 11);
                bulkInsertAndCheck(131, 20, 13);
            }
        }
示例#9
0
        public async Task SizeForSqlParameter()
        {
            await using var sw = new MsSqlWorker(ConnectionString);

            MsSqlWorker.DbParametersConstructor args = new SwParameters
            {
                { "number", 1 },
                { "name", default(string), DbType.String, ParameterDirection.Output, 100 },
            };

            Func <int, string, Task> assert = async(number, name) => {
                args[0].Value = number;
                await sw.ExecAsync("NumberName", args, commandType : CommandType.StoredProcedure);

                Assert.AreEqual(args["name"].Value, name);
            };

            await assert(2, "two");
            await assert(3, "three");
        }
示例#10
0
        public async System.Threading.Tasks.Task CheckAsyncIEnumerable()
        {
            await using var sw = new MsSqlWorker(ConnectionString);

            await using var tran = await sw.TransactionBeginAsync();

            var n = 1;

            await foreach (var x in sw.QueryAsync(
                               @"select number, square, sqrt, is_prime from dbo.numbers n",
                               dr => new {
                number = (int)dr[0],
                square = (long)dr[1],
                sqrt = (double)dr[2],
                is_prime = (bool)dr[3],
            },
                               transaction: tran
                               ))
            {
                Assert.AreEqual(x.number, n);
                ++n;
            }
        }
示例#11
0
        public bool AddLocation(string device_id, double lat, double lon, int radius)
        {
            try
            {
                if (_cacheDevicePerson.TryGetValue(device_id, out var person))
                {
                    using (var connection = new MsSqlWorker(GetConnection()))
                    {
                        connection.Exec(
                            @"
 insert into [Feedback] (id, person_id,external_reference, feedback_time, feedback_type, feedback_location )
                            select newid()
                        , (select top(1) phone from [PersonDevice] where device_id = @device_id)
                        , @device_id
                        , GETUTCDATE()
                        , 'device'
                        ,   geography::STPointFromText(@locationText, 4326)
						    .STBuffer(@radius)
", parameters: new SwParameters
                        {
                            { "device_id", device_id },
                            { "locationText", $"POINT( {lon.ToString(CultureInfo.InvariantCulture)} {lat.ToString(CultureInfo.InvariantCulture)})" },
                            { "radius", radius < 0 ? 0 : (radius > Radius ? Radius : radius) }
                        });
                        person.LastLocationUpdateRequest = DateTime.UtcNow;
                        return(true);
                    }
                }
                return(false);
            }
            catch (Exception e)
            {
                HandleExceptionSql(e);
                throw;
            }
        }
示例#12
0
        public async System.Threading.Tasks.Task MultipleAsyncEnumeration()
        {
            await using var sw = new MsSqlWorker(ConnectionString);

            var enumeration = sw.QueryAsync(
                @"select number, square, sqrt, is_prime from dbo.numbers n where n.number < @maxNumber",
                dr => new {
                i      = (int)dr[0],
                square = (long)dr[1],
            },
                new SwParameters
            {
                { "maxNumber", 10 },
            }
                );

            for (var i = 1; i <= 2; ++i)
            {
                await foreach (var x in enumeration)
                {
                    Assert.AreEqual(x.square, x.i * x.i);
                }
            }
        }
示例#13
0
        private void CheckUpdatePhones()
        {
            if (!LastPersonUpdates.HasValue)
            {
                var requestTime = DateTime.UtcNow;
                using (var connection = new MsSqlWorker(GetConnection()))
                {
                    var persons = connection.Query(
                        @"
IF(@lastTime is null or EXISTS(SELECT 1 FROM [ServiceTimestamp]
  WHERE [service_code] = 'Person' and last_start > @lastTime))
BEGIN
    SELECT 
    isnull(isnull(name_first, name_last), name_patr) as name,
    [quarantine_location].EnvelopeCenter().Lat as lat ,
    [quarantine_location].EnvelopeCenter().Long as lon,
    p.quarantine_stop,
    p.phone,
    pd.device_id
      FROM Person p
      left join [PersonDevice] pd on pd.[phone] = p.phone
END
", (dr) =>
                    {
                        var phone = dr.GetInt64(4);
                        return(new
                        {
                            Person = _cachePhonePerson.AddOrUpdate(phone,
                                                                   (p) => new PersonCacheObject()
                            {
                                Person = GetPersonFromReader(dr), LastUpdate = requestTime
                            },
                                                                   (p, old) =>
                            {
                                if (old.LastUpdate == requestTime)
                                {
                                    return old;
                                }
                                return new PersonCacheObject()
                                {
                                    Person = GetPersonFromReader(dr),
                                    LastUpdate = requestTime,
                                    LastLocationUpdateRequest = old.LastLocationUpdateRequest,
                                };
                            }),
                            Phone = phone,
                            DeviceId = dr.GetNullableString(5)
                        });
                    }, parameters: new SwParameters
                    {
                        { "@lastTime", LastPersonUpdates },
                    }).ToArray();
                    if (persons?.Length > 0)
                    {
                        _cacheDevicePerson.Clear();

                        foreach (var p in persons)
                        {
                            if (p.DeviceId?.Length > 0)
                            {
                                _cacheDevicePerson[p.DeviceId] = p.Person;
                            }
                        }
                        foreach (var delPhone in _cachePhonePerson.Where(w => w.Value.LastUpdate != requestTime).Select(a => a.Key))
                        {
                            _cachePhonePerson.TryRemove(delPhone, out var _);
                        }
                    }
                    LastPersonUpdates = DateTime.UtcNow.AddSeconds(-1);
                }
            }
        }
示例#14
0
        private PersonCacheObject GetPersonFormDb(long?phone = null, string?device_id = null)
        {
            using (var connection = new MsSqlWorker(GetConnection()))
            {
                DateTime requestTime = DateTime.UtcNow;
                var      persons     = connection.Query(
                    @"
    SELECT 
    isnull(isnull(name_first, name_last), name_patr) as name,
    [quarantine_location].EnvelopeCenter().Lat as lat ,
    [quarantine_location].EnvelopeCenter().Long as lon,
    p.quarantine_stop,
    p.phone,
    pd.device_id
      FROM Person p
      left join [PersonDevice] pd on pd.[phone] = p.phone
    where (@phone is null or p.phone = @phone )
and (@device_id is null or pd.device_id = @device_id)
", (dr) =>
                {
                    var phone = dr.GetInt64(4);
                    return(new
                    {
                        Person = _cachePhonePerson.AddOrUpdate(phone,
                                                               (p) => new PersonCacheObject()
                        {
                            Person = GetPersonFromReader(dr), LastUpdate = requestTime
                        },
                                                               (p, old) =>
                        {
                            if (old.LastUpdate == requestTime)
                            {
                                return old;
                            }
                            return new PersonCacheObject()
                            {
                                Person = GetPersonFromReader(dr),
                                LastUpdate = requestTime,
                                LastLocationUpdateRequest = old.LastLocationUpdateRequest,
                            };
                        }),
                        Phone = phone,
                        DeviceId = dr.GetNullableString(5)
                    });
                }, parameters: new SwParameters
                {
                    { "@lastTime", LastPersonUpdates },
                }).ToArray();
                if (persons?.Length > 0)
                {
                    foreach (var p in persons)
                    {
                        if (p.DeviceId?.Length > 0)
                        {
                            _cacheDevicePerson[p.DeviceId] = p.Person;
                        }
                    }
                }
                return(persons?.FirstOrDefault().Person);
            }
        }
示例#15
0
        public void TestConfig()
        {
            bool dbExists;

            Assert.IsNotNull(ConnectionStringMaster);
            Assert.IsNotNull(ConnectionString);
            using (var sw = new MsSqlWorker(ConnectionStringMaster))
            {
                Assert.AreEqual("hello", sw.Query("select 'hello'", dr => dr[0]).Single());

                dbExists = sw.Query(
                    @"declare @true bit = 1, @false bit = 0;
                    SELECT CASE when DB_ID('sqlworker_test') IS NULL then @false else @true end;",
                    dr => (bool)dr[0])
                           .Single();
            }

            if (Config["recreateDb"]?.ToLower() == "true" || !dbExists)
            {
                using (var sw = new MsSqlWorker(ConnectionStringMaster))
                {
                    sw.Exec(@"
                        IF DB_ID('sqlworker_test') IS NOT NULL
                            ALTER DATABASE sqlworker_test SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
                        DROP DATABASE IF EXISTS sqlworker_test;
                        CREATE DATABASE sqlworker_test;
                        ALTER DATABASE sqlworker_test SET RECOVERY SIMPLE;"
                            );
                }

                using (var sw = new MsSqlWorker(ConnectionString))
                {
                    Assert.AreEqual("hello", sw.Query("select 'hello'", dr => dr[0]).Single());
                }

                using (var sw = new MsSqlWorker(ConnectionString))
                    using (var dt = new System.Data.DataTable("numbers"))
                    {
                        dt.Columns.Add("number", typeof(int));
                        dt.Columns.Add("square", typeof(long));
                        dt.Columns.Add("sqrt", typeof(double));
                        dt.Columns.Add("is_prime", typeof(bool));
                        dt.Columns.Add(new System.Data.DataColumn("as_text", typeof(string))
                        {
                            MaxLength = 400
                        });

                        sw.CreateTableByDataTable(dt, true);

                        sw.Exec(@"
                        CREATE UNIQUE CLUSTERED INDEX [PK_number] ON [dbo].[numbers]([number] ASC)
                        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
                    ");
                        sw.Exec(@"
                        CREATE UNIQUE NONCLUSTERED INDEX [IX_square] ON [dbo].[numbers]([square] ASC)
                        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
                    ");
                        sw.Exec(@"
                        CREATE UNIQUE NONCLUSTERED INDEX [IX_sqrt] ON [dbo].[numbers]([sqrt] ASC)
                        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
                    ");

                        sw.Exec(@"
CREATE PROCEDURE GetPrimeNumber
	@primePosition int,
    @number int output,
    @square bigint output,
    @sqrt float output
AS
BEGIN
    SELECT
        @number = number,
        @square = square,
        @sqrt = sqrt
    FROM numbers
    WHERE is_prime = 1
    ORDER BY number
    OFFSET @primePosition - 1 ROWS
    FETCH NEXT 1 ROWS ONLY;

    RETURN @@ROWCOUNT;
END");
                        sw.Exec(@"
CREATE PROCEDURE NumberName
    @number int,
    @name nvarchar(100) output
AS
BEGIN
    SELECT @name = as_text
    FROM numbers
    WHERE number = @number
END
");
                    }
            }
        }
示例#16
0
        public void CanExec()
        {
            using var sw = new MsSqlWorker(ConnectionString);

            sw.Exec("DELETE FROM sqlworker_test.dbo.numbers");
        }