Куча говна / Говнокод #9545 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
(require 'clsql)

(clsql:file-enable-sql-reader-syntax)

(clsql:connect
 '("localhost" "database" "user" "password")
 :database-type :mysql)

(defun how-many-goods-do-you-have (year month)
  (declare
   (type (integer 2000 2011) year)
   (type (integer 1 12) month))
  (clsql:select [item_id] [sale_date]
		:from "table"
		:where [or
		[is [null [sale_date]]]
		[< [sale_date]
		(clsql:sql 'str_to_date\(
			   (format
			    nil
			    "~a-~2,'0d-00"
			    year month)
			   '|, '%Y-%m-%d')|
			   )]]))

Эксперименты :)

Запостил: wvxvw wvxvw, (Updated )

Комментарии (14) RSS

    • Тут исполнение даже так себе ничего хромает 🙂 вместо
      where 'yyyy-mm-dd' < some_field
      получили
      where str_to_date('yyyy-mm-dd','%y-%m-%d') < some_field
      Ответить
      • на мой взгляд, оба случая недостаточно "lispish", я бы предпочёл что-то типа этого:
        (clsql:select "table"
          (clsql:where [< (clsql:to-date "yyyy-mm-dd") some-field]))
        to-date, вероятно, должен зависеть от диалекта sql
        Ответить
        • Там даже to-date никакой не нужен, это ж просто строка. Это объективное ориентирование подводит: сохранял же дату, вот с датой и нужно сравнить 🙂 В итоге переписалось как-то так (это не вся функция, да и рабочей никогда не была, просто эксперименты какие-то старые, нужно было что-то с clsql сделать, решил найти, и нашел 🙂

          (defun how-many-goods-do-you-have (year month)
            (declare
             (type (integer 2000 2012) year)
             (type (integer 1 12) month))
            (let ((search-date
          	 (format nil "~a-~2,'0d-00"
          	   year month)))
              (clsql:select [item_id] [sale_date] [acquisition_date]
          		  :from "table"
          		  :where
          		  [and
          		  [<= [acquisition_date] search-date]
          		  [or
          		  [is [null [sale_date]]]
          		  [> [sale_date] search-date]]])))
          Ответить
          • а как вложеные селекты?

            как-то для лиспа это неправильно, если селект не есть (select (from ...) (where ...) ...), потому что концепцию ломает.

            да и опять же: я бы разделил генерацию запросов от их исполнения. это здесь очень похоже не делается.

            ЗЫ с одной сторны. с другой, а на кой фиг? народ знает SQL и есть внешние тулзы для работы с ним - самый логичный и гибкий вариант это оставить запросы строками. и с нестандартизироваными хинтами граблей потом тоже не будет.
            Ответить
            • бенефиты у генераторов запросов одни и теже: потенциально большая переносимость между диалектами + более тесная интеграция с языком и проверки на этапе компиляции + дополнительная возможность абстракции (легко можно собирать запросы по частям в рантайме)
              Ответить
            • Не, запрос генерируется отдельно, или можно отдельно, если хочется. (clsql:sql ...) собственно это и делает. Просто внутри конкретной функции он сразу и создается и отсылается. Смысл дополнительного синтаксиса - ну я не знаю, возможно есть смысл, если оно динамически создается, чтобы случайно не создать чего-то непредвиденное. Там еще есть какой-то ОРМ и всякое такое, на что я никогда даже не смотрел 🙂 Может там и менеджеры какие-то хитрые есть. Просто никогда не нужно было.
              Вложенные селекты - интересно 🙂 Не знаю, никогда не нужно было, я только для каких-то совсем примитивных вещей использовал. Но как видно из примера выше - запихать любую строку можно в селект, ну ток выглядит страшновато 🙂
              Ответить
  • Люди, а что это за ЯП? Просто первый раз вижу такой синтаксис, молодой.)))
    Ответить
    • Тут может квадратные скобки могли смутить - это не типичный для CL синтаксис - такой вот ридер-макрос решили в clsql сделать. Зачем - я так толком никогда и не смотрел, возможно чтобы за регистром символов следить, или чтобы кодировка в Лиспе совпадала с кодировкой в базе - не знаю. А может просто так 🙂
      Ответить
      • Судя по всему, там происходит генерация ссылок на таблицы/поля таблиц + всяческая нормализация
        clsql-6.1.1/sql/syntax.lisp
        (defmacro file-enable-sql-reader-syntax ()
          "Turns on the SQL reader syntax for the rest of the file.
        The CL spec says that when finished loading a file the original
        *readtable* is restored.  clhs COMPILE-FILE"
          '(eval-when (:compile-toplevel :load-toplevel :execute)
            (setf *readtable* (copy-readtable))
            (set-macro-character *sql-macro-open-char* #'sql-reader-open)
            (set-macro-character *sql-macro-close-char* (get-macro-character #\)))))
        ;; ...
        (defun sql-reader-open (stream char)
          (declare (ignore char))
          (let ((sqllist (read-delimited-list #\] stream t)))
            (unless *read-suppress*
              (handler-case
                  (cond ((string= (write-to-string (car sqllist)) "||")
                         (cons (sql-operator 'concat-op) (cdr sqllist)))
                        ((and (= (length sqllist) 1) (eql (car sqllist) '*))
                         (apply #'generate-sql-reference sqllist))
                        ((sql-operator (car sqllist))
                         (cons (sql-operator (car sqllist)) (cdr sqllist)))
                        (t (apply #'generate-sql-reference sqllist)))
                (sql-user-error (c)
                  (error 'sql-user-error
                         :message (format nil "Error ~A occured while attempting to parse '~A' at file position ~A"
                                          (sql-user-error-message c) sqllist (file-position stream))))))))
        Ответить
        • А, ну собственно, по большей части похоже, что сделано для того, чтобы не пересекались уже определенные функции с ихними, типа [*] не совпадал с #'*.
          Ответить

Добавить комментарий

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8