change permissions
[clsql/s11.git] / examples / clsql-tutorial.lisp
blob1980e3db0f4acd70fe0b8f76406af4dcae0cf1b2
1 (asdf:operate 'asdf:load-op 'clsql)
3 (in-package #:clsql-user)
5 ;; You must set these variables to appropriate values.
6 (defvar *tutorial-database-type* nil
7 "Possible values are :postgresql :postgresql-socket, :mysql,
8 :oracle, :odbc, :aodbc or :sqlite")
9 (defvar *tutorial-database-name* "clsqltut"
10 "The name of the database we will work in.")
11 (defvar *tutorial-database-user* ""
12 "The name of the database user we will work as.")
13 (defvar *tutorial-database-server* ""
14 "The name of the database server if required")
15 (defvar *tutorial-database-password* ""
16 "The password if required")
18 (clsql:def-view-class employee ()
19 ((emplid
20 :db-kind :key
21 :db-constraints :not-null
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 :initarg :email)
36 (companyid
37 :type integer
38 :initarg :companyid)
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 :initarg :managerid)
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))
58 (clsql:def-view-class company ()
59 ((companyid
60 :db-kind :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 :initarg :presidentid)
70 (president
71 :reader president
72 :db-kind :join
73 :db-info (:join-class employee
74 :home-key presidentid
75 :foreign-key emplid
76 :set nil))
77 (employees
78 :reader company-employees
79 :db-kind :join
80 :db-info (:join-class employee
81 :home-key companyid
82 :foreign-key companyid
83 :set t)))
84 (:base-table company))
86 ;; Connect to the database (see the CLSQL documentation for vendor
87 ;; specific connection specs).
88 (case *tutorial-database-type*
89 ((:mysql :postgresql :postgresql-socket)
90 (clsql:connect `(,*tutorial-database-server*
91 ,*tutorial-database-name*
92 ,*tutorial-database-user*
93 ,*tutorial-database-password*)
94 :database-type *tutorial-database-type*))
95 ((:odbc :aodbc :oracle)
96 (clsql:connect `(,*tutorial-database-name*
97 ,*tutorial-database-user*
98 ,*tutorial-database-password*)
99 :database-type *tutorial-database-type*))
100 (:sqlite
101 (clsql:connect `(,*tutorial-database-name*)
102 :database-type *tutorial-database-type*)))
104 ;; Record the sql going out, helps us learn what is going
105 ;; on behind the scenes
106 (clsql:start-sql-recording)
108 ;; Create the tables for our view classes
109 ;; First we drop them, ignoring any errors
110 (ignore-errors
111 (clsql:drop-view-from-class 'employee)
112 (clsql:drop-view-from-class 'company))
114 (clsql:create-view-from-class 'employee)
115 (clsql:create-view-from-class 'company)
118 ;; Create some instances of our view classes
119 (defvar company1 (make-instance 'company
120 :companyid 1
121 :name "Widgets Inc."
122 ;; Lenin is president of Widgets Inc.
123 :presidentid 1))
125 (defvar employee1 (make-instance 'employee
126 :emplid 1
127 :first-name "Vladamir"
128 :last-name "Lenin"
129 :email "lenin@soviet.org"
130 :companyid 1))
132 (defvar employee2 (make-instance 'employee
133 :emplid 2
134 :first-name "Josef"
135 :last-name "Stalin"
136 :email "stalin@soviet.org"
137 :companyid 1
138 ;; Lenin manages Stalin (for now)
139 :managerid 1))
141 (clsql:update-records-from-instance employee1)
142 (clsql:update-records-from-instance employee2)
143 (clsql:update-records-from-instance company1)
145 ;; lets use the functional sql interface
146 (clsql:locally-enable-sql-reader-syntax)
148 (format t "The email address of ~A ~A is ~A"
149 (first-name employee1)
150 (last-name employee1)
151 (employee-email employee1))
153 (setf (employee-email employee1) "lenin-nospam@soviets.org")
155 ;; Update the database
156 (clsql:update-records-from-instance employee1)
158 (let ((new-lenin (car
159 (clsql:select 'employee
160 :where [= [slot-value 'employee 'emplid] 1]
161 :flatp t))))
162 (format t "His new email is ~A"
163 (employee-email new-lenin)))
166 ;; Some queries
168 ;; all employees
169 (clsql:select 'employee)
170 ;; all companies
171 (clsql:select 'company)
173 ;; employees named Lenin
174 (clsql:select 'employee :where [= [slot-value 'employee 'last-name]
175 "Lenin"])
177 (clsql:select 'company :where [= [slot-value 'company 'name]
178 "Widgets Inc."])
180 ;; Employees of Widget's Inc.
181 (clsql:select 'employee
182 :where [and [= [slot-value 'employee 'companyid]
183 [slot-value 'company 'companyid]]
184 [= [slot-value 'company 'name]
185 "Widgets Inc."]])
187 ;; Same thing, except that we are using the employee
188 ;; relation in the company view class to do the join for us,
189 ;; saving us the work of writing out the SQL!
190 (company-employees company1)
192 ;; President of Widgets Inc.
193 (president company1)
195 ;; Manager of Josef Stalin
196 (employee-manager employee2)