Monday, 19 December 2011

SQLite

SQLite is SQL database engine small and ready to use. There are many Rebol scripts that handle SQLite, if you don't know this light SQL engine, you should visit:
http://www.sqlite.org/

The first script  I'll show you  is the following:
http://www.rebol.org/view-script.r?script=btn-sqlite.r

you have to put sqlite executable in the same directory of the script (Windows) or in /usr/bin/ (Linux). It's slow but it works this way:

>> do %btn-sqlite.r
>> db: open btn://localhost/test.db3
>> insert db "CREATE TABLE t1 (a int, b text, c text)"
== true
>> repeat i 25 [
[ insert db [{INSERT INTO t1 VALUES (?, ?, ?)} i (join "cool" i) (join "cool"
(25 + 1 - i))]
[ ]
== true
>> insert db "SELECT * FROM t1"
== true
>> probe db/locals/columns
["a" "b" "c"]
== ["a" "b" "c"]
>> res: copy/part db 10
== [["1" "cool1" "cool25"] ["2" "cool2" "cool24"] ["3" "cool3" "cool23"] ["4" "coo
l4" "cool22"] ["5" "cool5" "cool21"] ["6" "cool6"...
>> probe res
[["1" "cool1" "cool25"] ["2" "cool2" "cool24"] ["3" "cool3" "cool23"] ["4" "cool4"
"cool22"] ["5" "cool5" "cool21"] ["6" "cool6" "cool20"] ["7" "cool7" "cool19"] ["
8" "cool8" "cool18"] ["9" "cool9" "cool17"] ["10" "cool10" "cool16"]]
== [["1" "cool1" "cool25"] ["2" "cool2" "cool24"] ["3" "cool3" "cool23"] ["4" "coo
l4" "cool22"] ["5" "cool5" "cool21"] ["6" "cool6"...
>> probe length? res
10
== 10
>> insert db "DROP TABLE t1"
== true
>> close db


The second script is a little bit complex, you have to download the DLL or the Linux library in the script folder, then you can download the following script:
http://www.rebol.org/view-script.r?script=sqlite3.r

modify the script with the correct path to your sql3 library
Windows
sql: load/library %sqlite3.dll
or Linux
sql: load/library %libsqlite3.so
Here how it works:

>> db: sqlite-open %test.db
== 16121296
>> sqlite-exec db "CREATE TABLE t1 (a int , b text , c text);"
== []
>> sqlite-exec db "CREATE TABLE t2 (a int , b text , c text);"
== []
>> ; Testing of 1000 inserts one transaction at a time.
>> t: now/time/precise
== 12:14:23.765
>> repeat i 1000 [ sqlite-exec db reduce [{INSERT INTO t1 VALUES (?,"cool1","cool1");} i]
== []
>> delta: now/time/precise - t
== 0:02:22.422
>> print join "elapsed time = " delta
elapsed time = 0:02:22.422
>> ; Testing of 1000 inserts in one global transaction.
>> t: now/time/precise
== 12:26:49.687
>> sqlite-exec db "begin transaction;"
== []
>> repeat i 1000 [ sqlite-exec db reduce [{INSERT INTO t2 VALUES (?,"cool2","cool2");} i]
== []
>> sqlite-exec db "commit transaction;"
== []
>> delta: now/time/precise - t
== 0:00:00.281
>> print join "elapsed time = " delta
elapsed time = 0:00:00.281
>> ; Select now all data from both tables.
>> ;Just go through "res" block if you want to see the results.

>> res: copy []
== []
>> t: now/time/precise
== 12:29:49.875
>> repeat i 1000 [
insert tail res sqlite-exec/names db reduce ["SELECT * FROM t1 WHERE a=?;" i]
insert tail res sqlite-exec/names db reduce ["SELECT * FROM t2 WHERE a=?;" i]
]
== []
>> delta: now/time/precise - t
== 0:00:04.828
>> print join "elapsed time = " delta
elapsed time = 0:00:04.828
>> sqlite-close db


Then you can attach more databases in a single database, Robert Paluch, alias BobikCZ, shows us how to do it:

do %sqlite3.r ;; load sqlite driver
db: sqlite-open %myfirstdb.db ;; open first db file
sqlite-exec db {attach database 'myseconddb.db' as myseconddb} ;; attach my second db file
res: sqlite-exec db {select * from myseconddb.mytable} ;;resulting select etc..
;; there can be use also joins of tables


If you need to use SQLite over internet, you can with this script:
http://www.rebol.org/view-script.r?script=techfell-protocol.r
Here how it works:

db: open techfell://user:password@webhost.com
insert db "CREATE TABLE t1 (a int, b text, c text)"
repeat i 25 [
insert db [{INSERT INTO t1 VALUES (?, ?, ?)} i (join "cool" i) (join "cool" (25 + 1 - i))]
]
insert db "SELECT * FROM t1"
probe db/locals/columns
res: copy/part db 10
probe res
probe length? res
insert db "DROP TABLE t1"
close db

Friday, 16 December 2011

Buttons

Here a sample script for buttons:




REBOL [
Title: "Piles of Button Styles"
Date: 20-May-2000
Version: 1.1.0
File: %buttons.r
Author: "Carl Sassenrath"
Purpose: {Displays 52 button styles out of the hundreds possible.}
]
flash "Fetching image..."
pic: load-thru/binary http://www.rebol.com/view/palms.jpg
unview
group: ["rotary" "test" "button"]
view layout [
origin 20x10
backdrop effect [gradient 0x1 100.20.0]
vh1 "52 Button Click-up - Each with a different click effect..."
vtext bold "Here is a small sampling of the thousands of button effects you can create. (This is 78 lines of code.)"
at 20x80 guide
button "simple"
button form now/date
button "colored" 100.0.0
button "text colored" font [colors: [255.80.80 80.200.80]]
button with [texts: ["up text" "down text"]]
button "bi-colored" colors [0.150.100 150.20.20]
button with [texts: ["up color" "down color"] colors: [0.150.100 150.20.20]]
button "image" pic
button "color image" pic 200.100.50
button "flip color" pic with [effects: [[fit colorize 50.50.200][fit colorize 200.50.50]]]
button "blink" with [rate: 2 colors: [160.40.40 40.160.40]]
return
button "multiply" pic with [effects: [[fit][fit multiply 128.80.60]]]
button "brighten" pic with [effects: [[fit][fit luma 80]]]
button "contrast" pic with [effects: [[fit][fit contrast 80]]]
button "horiz flip" pic with [effects: [[fit][fit flip 1x0]]]
button "vert reflect" pic with [effects: [[fit][fit reflect 0x1]]]
button "invert" pic with [effects: [[fit][fit invert]]]
button "vert grad" with [effects: [[gradient 0x1 0.0.0 0.200.0] [gradient 0x1 0.200.0 0.0.0]]]
button "horiz grad" with [effects: [[gradient 1x0 200.0.0 200.200.200][gradient 1x0 200.200.200 200.0.0]]]
button "both grad" with [effects: [[gradient 1x0 140.0.0 40.40.200] [gradient 0x1 40.40.200 140.0.0]]]
button "blink grad" with [rate: 4 effects: [[gradient 1x0 0.0.0 0.0.200] [gradient 1x0 0.0.200 0.0.0]]]
button "blink flip" pic with [rate: 8 effects: [[fit][fit flip 0x1]]]
return
button "big dull button with several lines" 100x80 0.0.100
button "dual color" pic 50.50.100 100.50.50 100x80 with [edge: [color: 80.80.80]]
button "big edge" pic 100x80 with [edge: [size: 5x5 color: 80.80.80] effects: [[fit colorize 50.100.50][fit]]]
button "oval reflect" pic 50.100.50 100x80 with [effect: [fit reflect 1x0 oval]]
return
button "text on top" pic 100x80 with [font: [valign: 'top] effects: [[fit gradcol 1x1 200.0.0 0.0.200] [fit gradcol -1x-1 200.0.0 0.0.200]]]
button "text on bottom" pic 100x80 50.50.100 with [font: [valign: 'bottom] effects: [[fit][fit invert]]]
button "big text font" pic 100x80 with [font: [size: 24] effects: [[fit multiply 50.100.200][fit]]]
button "cross flip" pic 50.100.50 100x80 with [effect: [fit flip 0x1 reflect 0x1 cross]]
return
toggle "toggle"
toggle "toggle red" 100.0.0
toggle "toggle up" "toggle down"
toggle "toggle colored" 0.150.100 150.20.20
toggle "up color" "down color" 0.150.100 150.20.20
toggle "toggle multiply" pic with [effects: [[fit][fit multiply 128.80.60]]]
toggle "toggle contrast" pic with [effects: [[fit][fit contrast 80]]]
toggle "toggle cross" pic with [effects: [[fit][fit cross]]]
toggle "toggle v-grad" with [effects: [[gradient 0x1 0.0.0 0.200.0] [gradient 0x1 0.200.0 0.0.0]]]
toggle "toggle h-grad" with [effects: [[gradient 1x0 200.0.0 200.200.200][gradient 1x0 200.200.200 200.0.0]]]
toggle "toggle both" with [effects: [[gradient 1x0 140.0.0 40.40.200] [gradient 0x1 40.40.200 140.0.0]]]
return
rotary data group
rotary data reduce [now/date now/time]
rotary data group 100.0.0 0.100.0 0.0.100
rotary data group with [font: [colors: [255.80.80 80.200.80]]]
rotary data group with [colors: [0.150.100 150.20.20]]
rotary data group pic
rotary data group pic 200.100.50
rotary data group pic with [effects: [[fit colorize 50.50.200][fit colorize 200.50.50]]]
rotary data group with [effects: [[gradient 0x1 0.0.0 0.200.0] [gradient 0x1 0.200.0 0.0.0]]]
rotary data group with [effects: [[gradient 1x0 200.0.0 200.200.200][gradient 1x0 200.200.200 200.0.0]]]
rotary data group with [effects: [[gradient 1x0 140.0.0 40.40.200] [gradient 0x1 40.40.200 140.0.0]]]
]

Friday, 9 December 2011

Examples

Here you can find a lot of examples:
http://re-bol.com/examples.txt


Rebol Examples ( 7-21-10)

Bingo

Here you can find the link for a Bingo table to use as main screen for number extraction:
http://www.rebol.org/view-script.r?script=bingo.r
Screenshot:

If you click on the money, you can change the text; if you click on the image, you can change it.

Wednesday, 7 December 2011

Transferring files over internet

I was reading this script of Nick Antonaccio here:
http://www.rebol.org/view-script.r?script=binary-file-transfer.r

And I was mazed how is simple to send files with Rebol, here how it works:
First of all the receiver PC start to hear on TCP port 8 (but you can choose any port you wish:

; server/receiver - run first:
if error? try [port: first wait open/binary/no-wait tcp://:8] [quit]
mark: find file: copy wait port #""
length: to-integer to-string copy/part file mark
while [length > length? remove/part file next mark] [append file port]
view layout [image load file]


Then the sender crate and send the image:
; client/sender - run after server (change IP address if using on 2 pcs):
save/png %image.png to-image layout [box blue "I traveled through ports!"]
port: open/binary/no-wait tcp://127.0.0.1:8   ; adjust this IP address
insert file: read/binary %image.png join l: length? file #""
insert port file


and here the result:



There are just few lines of code, and this way you can transfer any file (music, videos, images, text, whatever) trough internet. Amazing!
You can learn more here: http://www.rebol.net/cookbook/recipes/0058.html

Tuesday, 6 December 2011

Using bitmap font

If you use DRAW dialect to create drawings with text like this:

view layout [
box black 100x100 effect [
draw [
pen red
line 30x30 50x20 70x70 40x50
pen blue
box 20x20 80x80
fill-pen 0.100.0
box 20x60 40x80
pen white
text 8x25 "Example"
fill-pen gold
flood 2x2 ]]]

You should obtain this result:
Sometime it happens that under Linux and MacOS you don't see the text Example.

LINUX SOLUTION
Under Linux it's easy to avoid font problems just declares the font to use (Example FreeSans.ttf):
my-font: make face/font [
name: "/usr/share/fonts/truetype/freefont/FreeSans.ttf"
with your path to font you want to use
size: 12]

and then

view layout [ box black 100x100 effect [
draw [
font my-font
line 30x30 50x20 70x70 40x50
text 8x25 "Now it works!"]]]


If you want your script cross-platform, you can set the lines just if the OS is Linux:

;check OS
switch system/version/4 [
4 [ ; it's Linux ]
3 [ ;it's Windows ]
2 [;it's MacOS X ]
]


USING BITMAP FONT (UNIVERSAL SOLUTION)
Another solution works for every OS: using the bitmap font. If you load your preferred bitmap font, your texts will be transformed in transparent images that you can use in VID, DRAW or wherever you like.
You can download the script from here:
http://www.rebol.org/view-script.r?script=bdf-font-library.r
If you run the script as is, the example will pop-up:
Comment the last line to avoid this behavior.
You may convert font from OpenType to BDF by  otf2bdf.
How to use:

  1. Load the font you want to use, in BDF format
  2. Create the transparent image(s) with you font and text
  3. Put them wherever you like
Example, with tektite font:

>> a: read %tektite.bdf
>> my-font: make bdf-font [ parse-font a ]
>> my-text: my-font/render "Hello world!"
>> view layout [image my-text ]

You can use the image both in VID and in DRAW!!!

Friday, 2 December 2011

Big numbers

Rebol can works with integers number to 9 digits, this means that you can write:

>> -999999999
== -999999999
>> 999999999
== 999999999

If you digit a bigger number is automatically transformed in a decimal precision number. Decimal numbers has 15 digits of precision:

>> 12345678901234567890123456789
== 1.23456789012346E+28


This behavior is normal, it's difficult to preform calculus that need more than 15 digits. For example in engineering field no more than 3-4 digits is necessary.
However it can be useful working with big integers, like indexing of pages, databases, etc.
Rebol can manipulate any longer integer, if you need it; just transform the number in a string and use the following script:

rebol [
Author: [ "Alban Gabillon"   "Massimiliano Vessi" ]
  Library: [
        level: 'intermediate
        platform: 'all
        type: tool
        domain: [math]
        tested-under: windows
        support: none
        license: none
        see-also: none
        ]
    History: [
        [1.0 22-mar-2007 "First version"]
        [2.1 29-11-2011 "Now it's more human usable"]
        ]
    Title:       "Bignumbers.r"
    File:   %bignumbers.r
    Owner:       "Alban Gabillon"
    Version:         2.1.0
    Date:       22-Mar-2007
    Purpose: {
    This script allows you to apply the four classical operations (big-add, big-subtract, big-divide, big-multiply) on very big positive integers.
    Size of the integers is only limited by the size of a rebol string since numbers are represented as strings.   }]
big-add: func [
    {add two big numbers }
    n1 [string!]
    n2 [string!]
    /local mem plus n result][
    n1: reverse copy n1
    n2: reverse copy n2
    mem: 0
    result: copy ""
    if (length? n1) < (length? n2) [n: n1 n1: n2 n2: n]
    while [not tail? n2][
        plus: to-string ((to-integer to-string n1/1) + (to-integer to-string n2/1) + mem)
        either (length? plus) = 1 [mem: 0 result: insert result plus/1][mem: 1 result: insert result plus/2]
        n1: next n1
        n2: next n2
        ]
    while [  not tail? n1][
        plus: to-string ((to-integer to-string n1/1) + mem)
        either (length? plus) = 1 [mem: 0 result: insert result plus/1][mem: 1 result: insert result plus/2]
        n1: next n1
        ]
    either mem = 1 [insert result #"1"][insert result copy n1]
    result: head result
    return  result
    ]
big-multiply: func   ["multiply two big numbers" n1 [string!] n2 [string!] /local temp ] [
    n1: reverse   copy n1
    n2: copy n2
    temp:   copy "0"
    foreach item n1 [      
        for i 1 (to-integer to-string item) 1 [                    
            temp: big-add   temp   n2        
            ]  
        append n2 "0"      
        ]  
    return temp
    ]
big-greater: func [
    {compare two bignumbers:
    return true if n1 > n2
    return false if n1 < n2
    return none if n1 = n2
    }

    n1 [string!]
    n2 [string!]][
    n1: reverse copy n1
    n2: reverse copy n2
    either (length? n1) <> (length? n2) [(length? n1) > (length? n2)][
        either equal? n1 n2 [none][
            n1: back tail n1
            n2: back tail n2
            while [n1/1 = n2/1][n1: back n1 n2: back n2]
            n1/1 > n2/1
            ]
        ]
    ]
big-sub: func [
    {substract the smallest big number from the largest one }
    n1 [string!]
    n2 [string!]
    /local mem minus n result][
    if big-greater n2 n1 [n: n1 n1: n2 n2: n]
    n1: reverse copy n1
    n2: reverse copy n2
    mem: 0
    result: copy ""
    while [not tail? n2][
        minus: to-string (((to-integer to-string n1/1) - mem) + (10 - (to-integer to-string n2/1)))
        either (length? minus) = 1 [mem: 1 result: insert result minus/1][mem: 0 result: insert result minus/2]
        n1: next n1
        n2: next n2
        ]
    while [all[mem = 1 not tail? n1]][
        minus: to-string ((to-integer to-string n1/1) + (10 - mem))
        either (length? minus) = 1 [mem: 1 result: insert result minus/1][mem: 0 result: insert result minus/2]
        n1: next n1
        ]
    insert result copy n1
    result: back tail result
    while [all [result/1 = #"0" not head? result]][result: back result]
    clear next result
    result: head result
    return reverse result
    ]
big-divide: func [
    {divide two big numbers   -
    output is a block of two numbers [quotient remainder]}

    n1 [string!]
    n2 [string!]
    /local   count   ][
        n1: copy n1 ;this avoid to modify the original block
        if big-greater n2 n1 [return reduce ["0" n1]] ;obvius
        if equal? n1 n2 [return reduce ["1" "0"]] ;obvius  
        count: "0"
        while [big-greater n1 n2 ] [
            n1: big-sub n1 n2
            count: big-add count "1"
            ]
        if equal? n1 n2 [
            count: big-add count "1"
            n1: "0"
            ]
        return   reduce [count n1]
        ]



It can be used this way (now I'll use small number as example):

>> big-add "253" "2"
== "255"
>> big-sub "253" "2"
== "251"
>> big-multiply "253" "2"
== "506"
>> big-divide "253" "2"
== ["126" "1"]


Real world examples:

>> big-add "123456789012345678901234567890" "123456789012345678901234567890"
== "246913578024691357802469135780"
>> big-sub "123456789012345678901234567890" "123456789012345678901234567890"
== "0"
>> big-multiply "123456789012345678901234567890" "123456789012345678901234567890"
== {15241578753238836750495351562536198787501905199875019052100}
>> big-divide "123456789012345678901234567890" "123456789012345678901234567890"
== ["1" "0"]