r8930: add database-create for pg socket, documentation improvements
[clsql.git] / examples / clsql-tutorial.lisp
1 (asdf:operate 'asdf:load-op 'clsql)
2
3 (in-package #:clsql-user)
4
5 ;; You must set these variables to appropriate values. 
6 (defvar *tutorial-database-type* nil 
7   "Possible values are :postgresql,:postgresql-socket :mysql or :sqlite")
8 (defvar *tutorial-database-name* ""
9   "The name of the database we will work in.")
10 (defvar *tutorial-database-user* "" 
11   "The name of the database user we will work as.")
12 (defvar *tutorial-database-server* ""
13   "The name of the database server if required")
14 (defvar *tutorial-database-password* "" 
15   "The password if required")
16
17 (clsql:def-view-class employee ()
18   ((emplid
19     :db-kind :key
20     :db-constraints :not-null
21     :nulls-ok nil
22     :type integer
23     :initarg :emplid)
24    (first-name
25     :accessor first-name
26     :type (string 30)
27     :initarg :first-name)
28    (last-name
29     :accessor last-name
30     :type (string 30)
31     :initarg :last-name)
32    (email
33     :accessor employee-email
34     :type (string 100)
35     :nulls-ok t
36     :initarg :email)
37    (companyid
38     :type integer)
39    (company
40     :accessor employee-company
41     :db-kind :join
42     :db-info (:join-class company
43                           :home-key companyid
44                           :foreign-key companyid
45                           :set nil))
46    (managerid
47     :type integer
48     :nulls-ok t)
49    (manager
50     :accessor employee-manager
51     :db-kind :join
52     :db-info (:join-class employee
53                           :home-key managerid
54                           :foreign-key emplid
55                           :set nil)))
56   (:base-table employee))
57
58 (clsql:def-view-class company ()
59   ((companyid
60     :db-type :key
61     :db-constraints :not-null
62     :type integer
63     :initarg :companyid)
64    (name
65     :type (string 100)
66     :initarg :name)
67    (presidentid
68     :type integer)
69    (president
70     :reader president
71     :db-kind :join
72     :db-info (:join-class employee
73                           :home-key presidentid
74                           :foreign-key emplid
75                           :set nil))
76    (employees
77     :reader company-employees
78     :db-kind :join
79     :db-info (:join-class employee
80                           :home-key companyid
81                           :foreign-key companyid
82                           :set t)))
83   (:base-table company))
84
85 ;; Connect to the database (see the CLSQL documentation for vendor
86 ;; specific connection specs).
87 (clsql:connect `(,*tutorial-database-server* 
88                ,*tutorial-database-name*
89                ,*tutorial-database-user* 
90                ,*tutorial-database-password*)
91              :database-type *tutorial-database-type*)
92
93 ;; Record the sql going out, helps us learn what is going
94 ;; on behind the scenes
95 (clsql:start-sql-recording)
96
97 ;; Create the tables for our view classes
98 ;; First we drop them, ignoring any errors
99 (ignore-errors
100  (clsql:drop-view-from-class 'employee)
101  (clsql:drop-view-from-class 'company))
102
103 (clsql:create-view-from-class 'employee)
104 (clsql:create-view-from-class 'company)
105
106
107 ;; Create some instances of our view classes
108 (defvar employee1 (make-instance 'employee
109                                :emplid 1
110                                :first-name "Vladamir"
111                                :last-name "Lenin"
112                                :email "lenin@soviet.org"))
113
114 (defvar company1 (make-instance 'company
115                               :companyid 1
116                               :name "Widgets Inc."))
117                               
118
119 (defvar employee2 (make-instance 'employee
120                                :emplid 2
121                                :first-name "Josef"
122                                :last-name "Stalin"
123                                :email "stalin@soviet.org"))
124
125 ;; Lenin manages Stalin (for now)
126 (clsql:add-to-relation employee2 'manager employee1)
127
128 ;; Lenin and Stalin both work for Widgets Inc.
129 (clsql:add-to-relation company1 'employees employee1)
130 (clsql:add-to-relation company1 'employees employee2)
131
132 ;; Lenin is president of Widgets Inc.
133 (clsql:add-to-relation company1 'president employee1)
134
135 (clsql:update-records-from-instance employee1)
136 (clsql:update-records-from-instance employee2)
137 (clsql:update-records-from-instance company1)
138
139 ;; lets us use the functional
140 ;; sql interface 
141 (clsql:locally-enable-sql-reader-syntax)
142
143
144 (format t "The email address of ~A ~A is ~A"
145         (first-name employee1)
146         (last-name employee1)
147         (employee-email employee1))
148
149 (setf (employee-email employee1) "lenin-nospam@soviets.org")
150
151 ;; Update the database
152 (clsql:update-records-from-instance employee1)
153
154 (let ((new-lenin (car
155                   (clsql:select 'employee
156                               :where [= [slot-value 'employee 'emplid] 1]))))
157   (format t "His new email is ~A"
158           (employee-email new-lenin)))
159
160
161 ;; Some queries
162
163 ;; all employees
164 (clsql:select 'employee)
165 ;; all companies
166 (clsql:select 'company)
167
168 ;; employees named Lenin
169 (clsql:select 'employee :where [= [slot-value 'employee 'last-name]
170                                 "Lenin"])
171
172 (clsql:select 'company :where [= [slot-value 'company 'name]
173                                "Widgets Inc."])
174
175 ;; Employees of Widget's Inc.
176 (clsql:select 'employee
177             :where [and [= [slot-value 'employee 'companyid]
178                            [slot-value 'company 'companyid]]
179                         [= [slot-value 'company 'name]
180                            "Widgets Inc."]])
181
182 ;; Same thing, except that we are using the employee
183 ;; relation in the company view class to do the join for us,
184 ;; saving us the work of writing out the SQL!
185 (company-employees company1)
186
187 ;; President of Widgets Inc.
188 (president company1)
189
190 ;; Manager of Josef Stalin
191 (employee-manager employee2)