Introduction to Redis

### Exercise: Introducing Lua

Lua stores data in variables, that are declared and initialized by specifying the variable name and using the assignment operator (=) to assign a value. Lua core datatypes are nil (null), number (combines both int and float), boolean, and strings.

```> x = 5
> x
5
> blank = nil
> blank
nil
> is_true, is_false = true, false
> is_true
true
> is_false
false
> message = "Redis with Lua is cool."
> message
Redis with Lua is cool.
>
```

A table in Lua is similar to the hash type in Redis, where a unique set of keys are mapped to a set of values. To retrieve a value from a table by key, either use square brackets [] or use the . operator if the key is a valid Lua identifier.

```> table1 = {}
> table1 = "The first value in table1"
> table1["second"] = "The second value in table1"
> table1
table: 0000000000620900
> table1
The first value in table1
> table1.second
The second value in table1
>
```

The standard mathematical operations are multiplication *, division /, addition +, subtraction -.

```> 3*5
15
> 12/2
6.0
> 896-785
111
> 129+745
874
> (2+3) * 5
25
>
```

Lua strings can concatenated using two periods; ... To create a Lua multi-line string without any character escaping, use double square brackets at the beginning [[ and at the end ]].

```> message = "Redis is SOOO fast"
> message
Redis is SOOO fast
> readme = [[The way to a good a project is
>> good documentation and plenty of coffee]]
The way to a good a project is
good documentation and plenty of coffee
>
```

Lua has the standard if/then conditional branching as well as various looping structures for tables. The do while and repeat until are similar looping structures with main difference being that the repeat until will execute at least once per loop. Lua has two types of for loops; the first takes a start value, end value, and increment while the second for type takes an iterator over a table and iterates through each key-value pair in the table.

```> x = 3.14
> if x > 10 then
>>    print("X is greater than 10")
>> elseif x == 2 then
>>    print("X is 2")
>> else
>>    print("X is "..x)
>> end
X is 3.14
>
> table2 = {20, 5, 60}
> sum, counter = 0, 1
> #table2
3
> while counter <= #table2 do
>>     sum = sum + table2[counter]
>>     counter = counter + 1
>> end
> print("The sum is ", sum)
The sum is      85
> sum, counter = 0, 1
> repeat
>>     sum = sum + table2[counter]
>>     counter = counter + 1
>> until counter > #table2
> print("The sum is: ", sum)
The sum is:     85
> sum = 0
> for counter = 1, #table2, 1 do
>>     sum = sum + table2[counter]
>> end
> print("The sum is: ", sum)
The sum is:     85
> for counter, num in ipairs(table2) do
>>     sum = sum + num
>> end
> print("The sum is: ", sum)
The sum is:     170
>
```

To create a function in Lua, use the function keyword.

```> crazy_eight = function(a_table)
>>     sum = 0
>>     for counter =1, #a_table, 1 do
>>         sum = sum + a_table[counter]*8
>>     end
>>     return sum
>> end
> crazy_eight(table2)
680
```

### Commands for Lua Scripting

• EVAL numkeys key [key ...] arg [arg …]
• EVALSHA sha1 numkeys key [key …] arg [arg ...]

### Exercise: First Lua Script

Lua scripts can be run using the EVAL and EVALSHA commands. Within the Lua script, Redis commands can be run using the `redis.call` and `redis.pcall` Lua functions. The difference between the two is that if an error occurs evaluating the `redis.pcall`, Lua will capture and return the error while `redis.call` will raise a Lua error and the EVAL command will also return an error.

```127.0.0.1:6379> EVAL "return {KEYS,KEYS,ARGV,ARGV}" 2 Book:1 Book:2 "War and Peace" "Critique of Pure Reason"
1) "Book:1"
2) "Book:2"
3) "War and Peace"
4) "Critique of Pure Reason"
127.0.0.1:6379> EVAL "return redis.call('SET', 'Book:1', 'War and Peace')" 0
OK
127.0.0.1:6379> GET Book:1
"War and Peace"
```

The EVALSHA command's first argument it is the SHA1 digest script instead of the script itself. Use the SCRIPT LOAD command to load script first and then use the resulting SHA1 to run script on the server

```127.0.0.1:6379> SCRIPT LOAD "return {KEYS,KEYS,ARGV,ARGV}"
"a42059b356c875f0717db19a51f6aaca9ae659ea"
127.0.0.1:6379> EVALSHA a42059b356c875f0717db19a51f6aaca9ae659ea 2 Book:1 Book:2 "War and Peace" "Critique of Pure Reason"
1) "Book:1"
2) "Book:2"
3) "War and Peace"
4) "Critique of Pure Reason"
```

## References and Resources

1. From the redis.io website: topic on EVAL
2. Lua Language homepage