1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* Each test should first create a table with two columns, insert 8,192 identical rows 'Alice', 1000.
   Then (the timed part) it should total the second column ( result 8,192,0000 ) and do this 1,000 times.
*/ 

#[test]
fn sqlite_test() {
    let connection = sqlite::open(":memory:").unwrap();

    let sql = "
    CREATE TABLE users (Id INTEGER PRIMARY KEY, name TEXT, age INTEGER);
    INSERT INTO users(name,age) VALUES ('Alice', 1000);";
    connection.execute(sql).unwrap();

    let sql = "INSERT INTO users(name,age) SELECT name, age FROM users";

    // Create 8192 records (each iteration should double number of records)
    for _i in 0..13 {
        connection.execute(sql).unwrap();
    }

    let start = std::time::SystemTime::now();
    for _i in 0..1000 {
        let sql = "SELECT SUM(age) FROM users";
        connection.execute(sql).unwrap();
    }
    println!(
        "sqllite test took {} milli-seconds",
        start.elapsed().unwrap().as_millis()
    );
}

#[test]
fn rustdb_test() {
    use crate::*;

    let stg = AtomicFile::new(MemFile::new(), MemFile::new());

    let mut bmap = BuiltinMap::default();
    standard_builtins(&mut bmap);
    let bmap = Arc::new(bmap);

    let spd = SharedPagedData::new(stg);
    let wapd = AccessPagedData::new_writer(spd.clone());
    let db = Database::new(wapd, "", bmap.clone());

    let mut tr = GenTransaction::default();

    let sql = "
    CREATE SCHEMA test GO
    CREATE TABLE test.users (name string, age int) GO";

    db.run(&sql, &mut tr);

    let sql = "DECLARE @i int SET @i = 8192
      WHILE @i > 0
      BEGIN
        INSERT INTO test.users(name,age) VALUES ('Alice', 1000)
        SET @i -= 1
      END";

    db.run(&sql, &mut tr);

    let start = std::time::SystemTime::now();

    for _i in 0..1000 {
        let sql = "DECLARE @total int FOR @total += age FROM test.users BEGIN END SELECT ''|@total";
        let mut tr = GenTransaction::default();
        db.run(&sql, &mut tr);
        assert_eq!(tr.rp.output, b"8192000");
    }

    println!(
        "rustdb test took {} milli-seconds",
        start.elapsed().unwrap().as_millis()
    );
}

#[test]
fn rustdb_direct_test() {
    use crate::*;

    let stg = AtomicFile::new(MemFile::new(), MemFile::new());

    let mut bmap = BuiltinMap::default();
    standard_builtins(&mut bmap);
    let bmap = Arc::new(bmap);

    let spd = SharedPagedData::new(stg);
    let wapd = AccessPagedData::new_writer(spd.clone());
    let db = Database::new(wapd, "", bmap.clone());

    let mut tr = GenTransaction::default();

    let sql = "
    CREATE SCHEMA test GO
    CREATE TABLE test.users (name string, age int) GO";

    db.run(&sql, &mut tr);

    let sql = "DECLARE @i int SET @i = 8192
      WHILE @i > 0
      BEGIN
        INSERT INTO test.users(name,age) VALUES ('Alice', 1000)
        SET @i -= 1
      END";

    db.run(&sql, &mut tr);

    let start = std::time::SystemTime::now();

    for _i in 0..1000 {
        let ut = db.table("test", "users");
        let mut total = 0;
        for (pp, off) in ut.scan(&db) {
                let p = &pp.borrow();
                let a = ut.access(p, off);
                total += a.int(1);
        }
        assert_eq!(total, 8192000);
    }

    println!(
        "rustdb direct test took {} milli-seconds",
        start.elapsed().unwrap().as_millis()
    );
}