SQLite в Golang - как использовать, на примере Telegram-бота

Sdílet
Vložit
  • čas přidán 31. 05. 2024
  • В этом видео мы научимся использовать SQLite в Go на примере моего Telegram-бота из прошлой серии уроков. Попутно научим бота использовать более продвинутое хранилище.
    Плейлист со всеми видео по этому Telegram-боту: • Telegram Bot на Golang
    Код проекта с разбиением на комииты по урокам: github.com/GolangLessons/Read...
    ----
    🔥 Конкурс: розыгрыш онлайн-билет на конференцию Saint HighLoad++ - одну из самых известных русскоязычных IT-конференций.
    Условия участия в конкурсе:
    - ознакомиться с программой конференции - bit.ly/3cAHI7x
    - выбрать наиболее интересный доклад (или несколько)
    - рассказать, какой доклад(ы) понравился и почему, заполнив форму forms.gle/kKJKU2KXWbwZVG6D8
    Чем убедительней будут аргументы, тем больше шансов, что билет достанется именно вам.
    Результаты конкурса будут объявлены 12 августа в моём Телеграм-канале: t.me/ntuzov
    Там же будут новости о возможных изменениях.
    Конференция проходит 22 и 23 сентября в Питере и онлайн.
    Подробное описание тут: bit.ly/3cAHI7x
    Здесь же можно купить билеты, если в розыгрыше вам не повезет.
    ----
    ❤️ Если у вас есть желание поддержать развитие канала:
    / tuzov
    boosty.to/nikolay.tuzov
    - 👾 Мой канал в Telegram: t.me/ntuzov
    - 🗣 Чат в Telegram: t.me/+zsSZ63wEJDs3NGVi
    - 👀 Golang Digest: t.me/golang_digest - мои регулярные подборки интересных материалов по Go.
    ----
    Тайм-коды
    00:00 Вступление
    00:16 Для кого этот ролик?
    00:26 Почему именно SQLite?
    01:10 Конкурс - 2000 подписчиков
    01:30 Интерфейс Storage
    01:58 SQLite-реализация Storage
    02:37 Установка соединения с БД
    03:36 Какием методы будем реализовывать
    03:56 Метод Save()
    07:36 Метод PickRandom()
    10:18 Метод Remove()
    10:47 Экранирование данных в SQL-запросах
    13:31 Метод IsExists()
    14:37 godoc-комментарии
    15:40 Функция Init() - инициализация хранилища
    17:04 Используем новый SQLite-Storage
    20:36 Фиксим мелкие баги
    23:10 Дебажим упавшего бота, stack trace
    24:17 Тестируем бота с новым хранилищем
    25:31 Конкурс - условия
    26:38 Заключение
    #golang #go #tuzov

Komentáře • 29

  • @nikolay_tuzov
    @nikolay_tuzov  Před rokem +3

    ❤ Если у вас есть желание поддержать развитие канала:
    www.patreon.com/tuzov
    boosty.to/nikolay.tuzov
    - 👾 Мой канал в Telegram: t.me/ntuzov (здесь же будут новости и доп. информация по конкурсу)
    - 🗣 Наш чат - Gopher Club: t.me/+zsSZ63wEJDs3NGVi
    - 👀 Golang Digest: t.me/golang_digest - мои регулярные подборки интересных материалов по Go.

  • @user-zp5rt6qb4k
    @user-zp5rt6qb4k Před rokem +4

    Отличная подача. Требуем ролик про контексты!)

  • @mmkamron
    @mmkamron Před rokem +5

    Отличное видео, спасибо за урок!

  • @kinvain
    @kinvain Před rokem +4

    Добавлю свои пять копеект на предмет контекста. Мне кажется вы зря поменяли интерфейс. То есть, были одни методы, была реализация. По началу вы сделали всё правильно - реализовали интерфейс для нового хранилища. Но теперь, если вы вернётесь к файловому то вам придётся и его менять. Что, имхо, неправильно. Понятно что в данном случае вы единственый кто рулит кодом, но если бы пакет файлового хранилища был бы на аутсорсе то возникли бы проблемы.
    Как альтернативу яп, наверное, предложил бы передавать контекст в методе инициализации sqlite-хранилища. Тогда бы хранилище бы могло реализовывать существующий интерфейс, но скрывало бы что делает вызовы с контекстом.
    func (s *Storage) SavePage(p *Page) error {
    retrun s.savePage(s.ctx, p);
    }
    Или это плохая идея хранить контекст в структуре?

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +3

      Хорошо, что вы задаётесь такими вопросами, но ход мыслей неверный:
      1) ошибкой с моей стороны скорее было отсутствие контекста в изначальном интерфейсе. Вы правы - подгонять интерфейс под частные реализации - это плохо. Но контекст важен с подобных интерфейсах - Storage чаще всего будет подразумевать длительные операции, которые нужно ограничивать таймаутом. Если это всего лишь файловая система, то контекст можно просто проигнорировать.
      Возможно, мне стоило это голосом проговорить в видео.
      2) Передавать контекст при инициализации - это совсем мимо. Важно иметь рычаги для управлением конкретными вызовами конкретных функций. На каждый вызов отдельный контекст с отдельным таймаутом. Иначе мы просто отменим сразу все текущие операции, даже хорошие.
      В этом видео я как раз показал общепринятый подход.
      Но в целом, повторюсь, хорошо что вы задаётесь этими вопросами и не ленитесь обсуждать. Я бы предложил вам присоединиться к нашему чатику, можем там периодически обсуждать подобное: t.me/+WyjmnP6la_QyYjAy

  • @kinvain
    @kinvain Před rokem +3

    У вас очень хорошая подача материала. Много, но всё чётко и по делу.
    Как личное пожелание - хотелось бы увидеть добавление к боту машины состояния. Например, что бы пользователь мог запустить интерактивный процесс удаления записей. Бот показывает запись, пользователь отвечает нужно ли её удалить или пропустить. Оверинжениринг в случае данного бота, но иногда такое очень нужно, а толковых инструкций нет.

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +2

      Спасибо, подумаю над этой идеей

  • @yablusgame
    @yablusgame Před 2 měsíci +1

    Николай, отличные ролики!! А на счет мультиплеерного бота-игры в телеге не думали? Типа камень-ножницы-бумага или подобной?

    • @nikolay_tuzov
      @nikolay_tuzov  Před měsícem +1

      Не думал, но идея интересная, спасибо. Учту на будущее

    • @yablusgame
      @yablusgame Před měsícem

      @@nikolay_tuzov так или иначе, спасибо за реакцию. По сути, на вскидку, сложности с лимитами телеграм (частота запросов к api, частота отправки сообщений ботом во всё чаты 1/30 сек, в один чат в зависимости от объёма сообщений, количество коннектов к вебхук если вебхук, и возможно другие) а также реализация комнат горутинами и каналами. Нюансов много. А значит материал (кстати отсутствующий в виде обучения) востребованный. Добра Вам и успехов в Ваших делах!

  • @Dantesik1
    @Dantesik1 Před rokem +1

    Это просто шедевральное видео, Николай, я хочу от тебя детей

  • @qwerty-hk4by
    @qwerty-hk4by Před rokem +4

    Можно где-нибудь целиком код посмотреть?

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +3

      Да, конечно: ttps://github.com/GolangLessons/Read-Adviser-Bot
      Коммиты разбиты по уроукам.
      Добавил ссылку в описание.

  • @vladislav_artyukhov
    @vladislav_artyukhov Před 3 měsíci +1

    7:07 "Смотрим, что нам возвращает функция Exec. Это какие-то результаты, которые, в данный момент, нам не особенно интересны, и ошибка. Результат мы проигнорируем, а вот ошибку, конечно же, обработаем" - 🤣 Golang development прекрасен

    • @nikolay_tuzov
      @nikolay_tuzov  Před 3 měsíci

      Лучший комментарий! 😆

  • @dmitriishitikov9499
    @dmitriishitikov9499 Před 5 měsíci

    А будет ролик про контекст?

  • @user-eq8px2pd7n
    @user-eq8px2pd7n Před rokem +2

    Привет, спасибо за серию таких крутых уроков! В твоем репозитории я увидел коммит, в котором ты добавил контекст ко всем методам клиента, добавлял контекст при отправке запроса. И еще ты добавил контекст к методам интерфейса storage, при этом его там не использовал. Ответь пожалуйста, зачем ты это сделал? Где я могу найти ответ на этот вопроc? Может книга есть или статья какая-то?

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +2

      Так я в этом видео и объяснял, зачем.
      Переданный контекст я использовал только в реализации sqlite - передавал его в методы db.

  • @Al.Sy.
    @Al.Sy. Před rokem +4

    Тема контекста интересует.

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +3

      Учту, спасибо. В будущем точно планирую об этом рассказать.

  • @TheDavBag
    @TheDavBag Před rokem

    почему у реализаций Storage методы вызываются с поинтером на ресивер?

  • @stassereduk7053
    @stassereduk7053 Před rokem +2

    Спасибо большое за видео! Понятным и доступным языком, как для меня начинающего. Только есть вопрос по установке go-sqlite3 через утилиту go get. При попытке установить выскакивает ошибка: "компилятор C "gcc" не найден". Подскажите в чем может быть причина, где искать решение?

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +1

      Не сталкивался с таким. Напиши точный текст ошибки и команду, которую пишешь.
      А лучше заходи в наш чатик, и задай вопрос там, поможем: t.me/+WyjmnP6la_QyYjAy

  • @OleksandrRiznyk
    @OleksandrRiznyk Před 6 měsíci

    Николай, а если бот на go делает запрос к какому-то API для получения данных в JSON и отдаёт пользователю их, нужны ли там рутины? Как вообще понять в какой момент они нужны, когда пользователей 100-1000-10000? Бот для разработки на 100 пользователей и 10000 это очень разные вещи или же бот сразу делается таким, чтобы он мог работать с большим количеством юзеров? На ютубе в основном очень простые видео и мало интересные, по сути такой себе деревянный hello world бот, лишь единичные нормальные видео, а у вас едвали не самый лучший или самый лучший плейлист по боту, где объясняется что-то дальше, чем простейшее и объясняется тщательно, чётко и интересно

  • @arnowt
    @arnowt Před rokem

    Подскажите как красиво передать имя таблицы в SQL запрос? Так чтобы IDE по-прежнему понимал диалект sql
    Понимаю что можно конкатенацию делать или тот же sprintf, но все это не красиво. А держать имя таблиц в константах бывает очень удобно особенно в стадии разработки.

    • @arnowt
      @arnowt Před rokem

      В питоне или пхп, я использую форматные строки "select * from {tableName} where id = ?"

  • @user-td5bw9rt2g
    @user-td5bw9rt2g Před rokem +1

    Небольшой рассинхрон звука и видео.

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem

      Да, бывает такое. С этим порой сложновато бороться(

  • @gopherz3144
    @gopherz3144 Před rokem +1

    Как же у него голос похож на Геннадия Горина. а так, классный урок