В этой части я дойду до момента, когда пришла смс-ка «Не звони и не пиши мне больше!!!!»

Первая часть тут, вторая тут.
4,5 года назад я имел неосторожность начать писать свою криптовалюту на совсем неподходящем для этого дела языке — на PHP. В итоге, конечно, написал (я упрямый), но получился костыль на костыле и то, что оно вообще работало было просто какой-то магией.
Сразу хочу предупредить, программер я самоучка-недоучка и пишу код, мягко сказать, неидеально.

Началось всё с того, что я расстался с девушкой, по имени Катя и в этот же день (4 апреля 2015-го) решил изучить Go и переписать свою криптовалюту. Писать про Катю не под спойлерами не могу, т.к. хабр всё же для IT-шных статей, а не для любовных рассказов и суровые айтишники, которым интересна тема Go, могут просто не обращать внимание на спойлеры «про Катю».

Итог 8 месяцев: приложение работает на Win (64/32), OSX(64/32), Linux(64/32), FreeBSD(64/32), Android, IOS (будет круто, если кто-то закинет в App Store).
Общего кода ~73к строк, кода под разные ОС где-то несколько сотен строчек.
40к — обработка/генерация блоков/тр-ий, 17.5к — контроллеры для интерфейса, 15.5к — шаблоны
Поддерживаются PostgreSQL, SQLite, MySQL.

Тех, кто будет тестировать мое творение, предупреждаю — могут быть баги, и если у Вас есть время, черкните о них, пожалуйста, на darwin@dcoin.club или в личку на хабре. Пожелания и советы тоже приветствуются.

В первых двух частях я рассказал про то, как в dcoin функционирует веб-сервер и про html/template.

В этой статье я расскажу про базы данных, плавное завершение приложения, шифрование и парсинг блоков

Про Катю
Всю ночь ни я, ни она не могли заснуть, просто молча лежали. В моей голове были мысли «нафиг её, другую найду, неадекватная она». О чем думала она, я не знаю.
Утром почему-то я снова почувствовал к ней влюбленность. Накормил завтраком и упаковал суп в контейнер, чтобы Катя на работе поела.

Базы данных


В dcoin я сделал поддержку sqlite, postgres, mysql. Для обычных десктопных приложений по умолчанию выбрана sqlite, т.к. не нужно ничего ставить дополнительно. Тем, кто будет поднимать свой dcoin-пул лучше выбирать между postgres и mysql.
За работу с SQL базами данных в golang отвечает пакет database/sql. К нему нужно подключать драйвер БД sqlite, postgresql, mysql.

Вначале я использовал только sqlite, затем решил подключить postgresql и mysql. Оказалось не очень сложно. Изменить пришлось только параметры для подключения к БД в sql.Open() и учесть различия в синтаксисе Sql-запросов
Тут моя реализация подключения к БД.
Обертки для работы с БД я не использовал, т.к. голые sql-запросы мне было удобнее переносить из старой версии Dcoin, по этой же причине в коде есть довольно убогие конструкции с преобразованием типов данных, полученных из БД.

Пара грабель, на которые я наступил:
1. Если забыть после db.Query(«sql») вызвать rows.Close(), то будет куча незакрытых коннектов.
2. defer нельзя вызывать до обработки ошибки, т.к. если будет ошибка, то row будет nil, а вызов rows.Close() приведет к панике. Вот так делать нельзя:

rows, err := db.Query("SELECT * FROM table")
defer rows.Close()
if err != nil {
	return err
}

Вот так верно:
rows, err := db.Query("SELECT * FROM table")
if err != nil {
	return err
}
defer rows.Close()

Про Катю
Дальше она снова много раз переносила встречу. Не знаю почему, но с каждым днем я всё сильнее и сильнее влюблялся в неё. Я хотел только её, думал только о ней. В какой-то момент поймал себя на мысли, что хочу на ней жениться. Случайно нашел стихи Кати на сайте stihi.ru, после одного стиха даже прослезился, там было про то, как с ней плохо обходились её бывшие парни. Я сходил с ума, это чувство, что я испытывал к ней было для меня странно и не понятно, у меня такого состояния еще никогда не было.

Json


type minersDataType struct {
	hosts    string          `json:"hosts"`
}
func main() {
	result_ := minersDataType{hosts: "pool.dcoin.club"}
	result, _ := json.Marshal(result_)
}

result будет содержать "{}"
Если заменить hosts на Hosts, то всё будет работать и в result появится {«hosts»:«111111»}
type minersDataType struct {
	Hosts    string          `json:"hosts"`
}
func main() {
	result_ := minersDataType{Hosts: "pool.dcoin.club"}
	result, _ := json.Marshal(result_)
}

Я с этим долго тупил, поэтому делаюсь инфой, чтобы кто-то не наступил на те же грабли

Про Катю
Написал Кате, что люблю её, хочу быть только с ней. Свидания она всё равно продолжала переносить. Надоело, купил её любимые цветы и поехал к ней, чтобы увидеться. Зачем-то даже выучил один из её стихов. Приехал, дома никого нет. Телефон не отвечает.

Сигналы


Если в процессе парсинга блоков выйти из программы, то данные могут быть занесены не полностью и произойдет рассинхронизация. Например, транзакция по начислению средств обработается, а по списанию — нет. Поэтому важно плавно завершить работу, если поступил сигнал о закрытии приложения
SigChan = make(chan os.Signal, 1)
C.waitSig() // про это напишу ниже
go func() {
	signal.Notify(SigChan, os.Interrupt, os.Kill, syscall.SIGTERM)
	// ждем, пока придет сигнал
	<-SigChan
	// сообщаем демонам, что надо срочно завершать работу
	for i := 0; i < countDaemons; i++ {
		daemons.DaemonCh <- true
		answer := <-daemons.AnswerDaemonCh
	}
	// демоны завершили работу, теперь можно закрыть соединение с БД
	DB.Close()
}()

C.waitSig() — это нужно для windows, т.к. сигналы в windows Go не видит.
/*
#include <stdio.h>
#include <signal.h>

extern void go_callback_int();
static inline void SigBreak_Handler(int n_signal){
  go_callback_int();
}
static inline void waitSig() {
    #if (WIN32 || WIN64)
    signal(SIGBREAK, &SigBreak_Handler);
    signal(SIGINT, &SigBreak_Handler);
    #endif
}
*/
import (
	"C"
)
//export go_callback_int
func go_callback_int() {
	SigChan <- syscall.Signal(1)
}

Если приходит SIGBREAK или SIGINT, то вызывается сишный SigBreak_Handler, который вызывает go_callback_int, который шлет в канал SigChan инфу, что был сигнал о завершении.
В Dcoin обработка сигналов реализована тут

Про Катю
Написал ей в ВК, сказала, что тел дома забыла, а сейчас у подруги. Я написал, что подожду её. После чего получил «Не звони и не пиши мне больше!!!!». Вопросов задавать не стал, позвонил в соседнюю квартиру, попросил передать цветы Кате, когда она будет дома. Приехал домой, через несколько часов принял решение переписать Dcoin на Go.

Шифрование


Мне понадобилось зашифровать при помощи AES ключ в Go, а расшифровать в JS. Мучился где-то 2 дня. Оказывается IV надо передавать вместе с самим зашифрованным текстом. У меня эта функция находится тут

func Encrypt(password, text []byte) ([]byte, error) {
	iv := []byte(RandSeq(aes.BlockSize))
	c, err := aes.NewCipher(password)
	if err != nil {
		return nil, ErrInfo(err)
	}
	plaintext := PKCS5Padding([]byte(text), c.BlockSize())
	cfbdec := cipher.NewCBCEncrypter(c, iv)
	EncPrivateKeyBin := make([]byte, len(plaintext))
	cfbdec.CryptBlocks(EncPrivateKeyBin, plaintext)
	EncPrivateKeyBin = append(iv, EncPrivateKeyBin...)
	return EncPrivateKeyBin, nil
}

и расшифровка в JS:
            ivAndText = atob(text);
            iv = ivAndText.substr(0, 16);
            encText = ivAndText.substr(16);
            cipherParams = CryptoJS.lib.CipherParams.create({
                ciphertext: CryptoJS.enc.Base64.parse(btoa(encText))
            });

            password = CryptoJS.enc.Latin1.parse(hex_md5(password));
            var decrypted = CryptoJS.AES.decrypt(cipherParams, password, {mode: CryptoJS.mode.CBC, iv: CryptoJS.enc.Utf8.parse(iv), padding: CryptoJS.pad.Iso10126 });
            var decryptedText = hex2a(decrypted.toString());

Расшифровку я делаю в worker-е, иначе из-за синхронности ненадолго вешается браузер.

Парсинг блоков


Непосредственно за разбор блоков и занесение данных в таблицы отвечает пакет dcparser
Рассмотрим например, транзакцию регистрации нового юзерского ключа, по сути нового Dcoin-пользователя — new_user.go
NewUserInit отвечает за заполнение переменных, которые содержат данные этой транзакции. Тут их всего две — public_key и sign
NewUserFront отвечает за проверку данных. В частности, проверяет, является пользователь, который сгенерировал эту транзакцию майнером. Проверяет, нет ли превышения лимитов и пр.
NewUser заносит данные в БД
NewUserRollbackFront откатывает изменения, которые были занесены методом NewUserFront
NewUserRollback откатывает данные, которые были занесены методом NewUser
Аналогичные 4 метода есть для каждого из 70-и типов транзакций.
На минуточку представьте как парсятся > 270 000 блоков. 70 методов заносят данные в 180 таблиц и 1100 разных колонок. А затем то, что меня завораживает больше всего — откат всех данных по одному блоку в обратном порядке через Rollback и RollbackFront. Такой полный откат делается для тестирования корректности работы dcparser. Если где-то как-то неверно занеслись данные, то это сразу станет видно.

Про Катю
Через пару дней написал ей, что на несколько месяцев ухожу с головой в свой проект и попросил не беспокоить меня по пустякам. Через неделю от Кати пришла смс-ка.

Заключение


В следующих статьях я расскажу про то, как я немного изменил gomobile, добавив уведомления и работу в фоне для IOS и Android приложений.

Комментарии (69)


  1. SerCe
    15.01.2016 11:50
    +32

    В следующих статьях я расскажу про то, как я немного изменил gomobile, добавив уведомления и работу в фоне для IOS и Android приложений

    Про Катю то допишете, это же еще не конец?


    1. c-darwin
      15.01.2016 11:56
      +17

      Да, про Катю тоже напишу.


      1. ChapayHabr
        16.01.2016 09:24
        +5


  1. Singerofthefall
    15.01.2016 11:59
    +28

    Через неделю от Кати пришла смс-ка.
    Ну вот, на самом интересном месте…


    1. igordata
      17.01.2016 11:47
      +2

      Я беременна. Поженимся?


  1. EagleMoor
    15.01.2016 12:00
    +12

    Мне кажется что всех программистов это бесит больше всего. Когда что-то (кто-то) ломается и обратного кейса ты не видишь и продебажить не получается. Нам бы хоть причину знать, а тут последний пинг «не звони мне больше» и еще один «а вдруг она перезапустилась уже» =)

    Девушки, люди, будте адекватными. Если посылаете, то хоть причину скажите. А то некоторые в while (true) ожидание сваливаются =)


    1. aml
      15.01.2016 12:11
      +4

      Девушки иногда возвращают ошибку корректно, но поскольку парни её обычно обрабатывают так:

      for {
        if err := girl.attempt(); err != nil {
          log.Printf("attempt failed: %v, retrying", err)
          continue
        }
        break
      }
      

      то желание так делать у них быстро пропадает.


      1. EagleMoor
        15.01.2016 12:48
        +7

        По моему большенство вот так обрабатывает =)

        for {
            _ := girl.attempt()
        }
        


        1. pehat
          16.01.2016 13:11

          По-моему, большинство := ложит поверх girl.attempt(), а не сбоку.


          1. ColorPrint
            20.01.2016 20:07

            кладет же.


    1. vorphalack
      15.01.2016 12:25
      +15

      (голосом Винни-Пуха) Девушка это очень странный предмет, скандал уже есть — а причин еще нет.

      кстати, автор часом не изобрел Love-Hate Driven Programming?


    1. WinPooh73
      15.01.2016 13:15
      +5

      > Девушки, люди, будте адекватными.

      Скидывайте core dump!
      Ну, или хотя бы stack trace…


      1. neolink
        15.01.2016 13:25
        +6

        ага, тестовый доступ давайте…


        1. c01nd01r
          15.01.2016 13:27
          +1

          или конфиги для нормальной настройки логов…


    1. andyN
      15.01.2016 15:54
      +3

      Автором статьи походу просто манипулировали, игра в «ближе-дальше».


    1. Visions
      16.01.2016 01:28

      Возможно ему даже повезло, что после масла ничего не случилось, т.к. похоже она «завирусована» по самый биос :))
      Думаю автор конечно заготовил для этого «виртуальное окружение», а возможно и развернул его… но после масла и поцелуев все-таки подхватил короткоживущий троян в свою ОС ((


  1. poxu
    15.01.2016 12:01
    +70

    По моему уже кто-то говорил, но тем не менее. Автор, перестань класть отрывки про Катю в спойлер. Оборачивай в спойлер отрывки про Go!


    1. EagleMoor
      15.01.2016 12:50
      +3

      Ради эксперимента можно вообще не оборачивать ни чего и даже мини заголовки не писать, что бы люди наконец-то начали читать статью =)


    1. monah_tuk
      18.01.2016 07:12
      +1

      Не! Тогда на GT перекинут :)


  1. neolink
    15.01.2016 12:02
    +24

    То чувство когда под спойлеры спрятана не та часть текста


    1. izac
      15.01.2016 13:53
      -2

      То чувство когда зашёл в статью прочитать про Катю, а не про Go.


  1. DenimTornado
    15.01.2016 12:35
    +11

    А был ли Катя?


    1. ximaera
      15.01.2016 15:28
      +3

      Второй сезон «Mr. Robot» не за горами, да.


    1. pehat
      16.01.2016 13:12

      lurkmore.to/Катя_Деткина


  1. matrixs
    15.01.2016 12:44
    +3

    Жду новых серий, надеюсь у вас получилось отладить Катю )


    1. Stas911
      15.01.2016 23:56
      +3

      Судя по заголовку, Катю пришлось полностью переписать на Машу…


  1. Juzujka
    15.01.2016 13:16
    +2

    Интересно ещё узнать, что думала Катя.
    А не мешали ли ей pet projects?

    Есть мол. чел., у него есть работа и личная жизнь.
    В личной жизни есть отношения с девушкой, друзья, хобби (pet project)…
    И если этот pet project занимает тот ресурс, который девушка считает своим, то отношения с ней будут не лучшими.

    Так вот, если у человека есть pet project, который отнимает несколько часов в день, то как ему относиться к отношениям с девушкой?
    Скорее всего, девушку не устроит, что нескольько часов в день после работы уходит на pet project, а не на неё.
    Или найти такую девушку, которая сама будет гореть его pet project, помогать, подгонять… Наверное, таких дефицит
    Или у неё есть свой pet project и она сама туда время сливает. Но это странно для девушки, они по-другому устроены.
    Или она трудоголичка.
    Или ей всё равно до мол.чел.
    Или умудриться объяснить ей, что это как бы так важно и для неё тоже… Но только без обмана! Это действительно нужно в её жизни при том, что ей время на отношения не хватает?
    Или ещё что-нибудь


    1. JustRoo
      15.01.2016 18:19
      +7

      Воу-воу-воу, а мнение pet-project'a о какой-то внезапно появившейся девушке, отнимающей столь ценное время, которое могло бы быть с пользой потрачено на взаимное развитие, тебя вообще не интересует? Или то, что она одного с тобой биологического вида, автоматически означает, что она лучше кода? Чёртовы органические шовинисты!


    1. 0xd34df00d
      17.01.2016 21:04

      Отчасти поэтому забил на попытки выстраивать отношения, решил выстраивать pet project'ы. Брат жив.


      1. Juzujka
        17.01.2016 22:46

        а как же вариант, при котором половинка помогает, вдохновляет?


        1. 0xd34df00d
          17.01.2016 23:30

          Эндогенного вдохновения хватает.


  1. c01nd01r
    15.01.2016 13:20
    +3

    Да автор ставит брейкпоины похлеще всех этих сериалов.

    >«Не звони и не пиши мне больше!!!!»
    >Через неделю от Кати пришла смс-ка.
    Не знаю, что там было в смс, но я б ее послал.


    1. kelegorm
      15.01.2016 13:35
      +13

      Снег идет… С первым днем зимы!


      1. teamfighter
        15.01.2016 17:02
        +4

        А автор в этот момент в Бильдяжках, да.


    1. BelBES
      15.01.2016 13:43
      -3

      Так для девушек код возврата

      Не звони и не пиши мне больше!!!!

      Это вообще практически синоним
      the program was successful

      (=


      1. c01nd01r
        15.01.2016 14:06

        Я понимаю, что бывают «эксепшены», но емае… Автор в любви признался, позаботился о ее желудке, домой приехал повидаться. Стоит под дверью, а ему тут такая смс.
        Нельзя к себе такое отношение допускать.


        1. poxu
          15.01.2016 14:17

          Ну а посмотрите с точки зрения девушки — его никто не звал, его никто не ждал, а он под дверью стоит. Кто его знает с какой целью. Кто его знает, что у этого программиста в голове. Нуегонахрен!


          1. ximaera
            15.01.2016 15:26
            +3

            Ещё и с подругами через VK перезнакомился (в прошлом посте). Многовато напора для трёх свиданий-то.

            Хотя, потеряв голову, какой только глупости не сделаешь.


        1. mekegi
          15.01.2016 15:37
          +1

          У Фейнмана в книгах «Вы конечно шутите мистер Фейнман» и «Какое тебе дело до того что думают другие» есть отличный алгоритм обращения с девушками, и там же еще немного рассуждений на тему «почему девчонкам не нравятся сопливые неуверенные в себе мальчишки»


          1. RedApe
            15.01.2016 23:09

            С одной стороны алгоритм есть, а с другой — сам Фейнман особо им и не пользовался. К тому же Фейнман описывает не всех, а некоторое-подмножество-девушек, которое взаимодействует с некоторым-подмножеством-юношей. Хотя, конечно, описание позволяет по-другому взглянуть на общение с Катями.


  1. Sasha_Pitenin
    15.01.2016 14:23
    +3

    Страсти, интриги и код :-)


  1. DrPass
    15.01.2016 14:51
    +9

    Помню, в 2004-м году, когда Катя (уж не знаю, эта же самая или они все одинаковые) съела мне моск по поводу моей работы, я стал программистом. Катю, впрочем, бросил одновременно со старой работой.


  1. Mecid
    15.01.2016 15:14
    +7

    Слишком мало Кати в этот раз…


  1. RZimin
    15.01.2016 16:02
    +3

    Жаль нет возможности title для спойлера делать жирным, а то аж пролистал случайно.


  1. skey
    15.01.2016 16:20

    А Катя знает об этих статьях и о том, что является главным героем?


    1. c-darwin
      15.01.2016 16:42

      Нет, не знает. И я не уверен, стоит ли ей про это говорить.


      1. kampaster
        15.01.2016 16:55

        Хмм, это намёк на то что всё наладилось?
        Когда уже следующая статья то? =)


        1. c-darwin
          15.01.2016 17:11

          Нет, не намек :)
          Следующая статья пока в процессе, там про android и gomobile, как только допишу, вставлю «про Катю» и выложу.


  1. Aspire89
    15.01.2016 17:14
    -3

    читаю только про Катю


    1. erlyvideo
      16.01.2016 00:44

      Cmd+F, да


  1. IaIojek
    15.01.2016 17:50
    +2

    Хороший подход к написанию статьи. Прямо жизнь программиста в миниатюре — кодинг параллельно личной жизни. Но меня эта история тронула ещё и тем, что в ней я заметил несколько пересечения со своей. Я тоже встречался с девушкой по имени Катя. Длилось это 4.5 года. Когда у нас только начался разлад в середине этого срока, в попытках хоть как-то отвлечься, я начал писать свой js движок. После расставания в апреле 2015-го я так же подумал, что у меня теперь много свободного времени и почти полностью переработал его. Только помимо этого я ещё сменил город и место работы, почти как DrPass


  1. Visions
    15.01.2016 19:12
    +7

    Раз тут обсуждают в первую очередь Катю и Ваши с ней взаимоотношения;)) Прочитав про нее и комменты, странно было не увидеть рассмотрения довольно очевидной возможной гипотезы, а именно:
    Так часто поступают девушки имеющие, если сказать мягко — несколько «инрижек» параллельно… это не очень распространенный кейс, но довольно типичный… в такой ситуации они именно так себя и ведут с парнем, который среди остальных задействованных в интриге — с низким приоритетом!
    Возможно это будет не приятно осознавать, но пока ее не бросит тот (или те) кто для нее с большим приоритетом, то с тем у кого приоритет низкий — она так и будет себя вести… а потом, если не будет других кандидатов — она станет вдруг более «отзывчивой», но скорее всего только до того момента, пока на ее горизонте не появится другой :(

    По ключевым моментам в рамках такой концепции:
    — в кровати не было «продолжения» потому, что для некоторых девушек «такой флирт» это не измена, т.к. небыло самого главного для нее… т.е. «типо она не изменила» тому другому… а сделала это потому что он (другой) ее чем -то обидел в тот момент…
    — резкая реакция на неожиданный приезд и признания — это яркое чувство угрозы ее потенциальным отношениям с другим парнем
    — рассказы ее подруги — это обычная дружеская «солидарность» и согласованное желание не «полить» в случае отсутствия конкуренции за одного мужчину…

    Может все конечно и не так, но пока все к одному…


    1. ColorPrint
      20.01.2016 20:15

      Какая многопоточная девушка :D


  1. PapaBubaDiop
    15.01.2016 19:15
    +2

    Программисты любят, когда в кучу string'и и стринги. Потому что, как правило, в теме.


  1. Doktor_Gradus
    15.01.2016 21:46

    Интересный ход — поместить спойлер на картинку, я повёлся.


  1. Meklon
    15.01.2016 22:05
    +2

    У меня жена Катя) кажется, я все делаю правильно.


  1. erlyvideo
    16.01.2016 00:44
    +1

    Чувак, просто забей на Катю. Она просто не хочет быть с тобой.

    Ну т.е. это нормально, чувства там, эмоции, но блин, найдешь бабу получше.


    1. Alexufo
      16.01.2016 01:21
      +8

      Если пользоваться терминами Юнга, то Катя это «анима» автора статьи, а «анима» это такая же часть человеческого мироощущения как нога или рука. Поэтому советы «забей, найдешь получше» крайне вредны и только заставляют автора переписывать с php на что-то еще.

      Человек чувствует, что ему предлагают ампутировать какую-то часть его. Причем священную. Вопрос нужно ставить совсем по другому, начать с того что Катя не может обладать теми образами что ее наделяют, а следовательно — рассмотреть образ кати внутри мироощущения автора статьи шире и убедить его в том что та красота которую он видет конечно каким то образом совпадает с реальной Катей, но по факту настоящую красоту он чувсвует в себе. И она никуда никогда не уйдет, а останется с ним.
      Человек предпочел отвлечся от бесконечного внутреннего диалога с Катей интеллектуальными задачками, что является необычайно важным, поскольку в пассивно диванное время мы без веры в аниму нихрена делать не хотим, так как чувствуем ее не всегда так сильно.


      1. erlyvideo
        16.01.2016 10:41

        есть проще рецепт: Катя скоро уйдет от того джависта, к которому она ушла от автора. Тут надо её поймать на одну ночь, закрыть гештальт и вернуться на PHP.


  1. maggg
    16.01.2016 13:06

    На stihi.ru оказывается столько Кать…


  1. utrack
    16.01.2016 14:45

    Автор (и все остальные), раз уж ты играешь с json и sql одновременно — недавно словил хитрую граблю по этому поводу.

    Если в структуре есть любой тип, наследующий []byte, например json.RawMessage — то пакет sql это не увидит и будет обращаться с ним в пуле объектов как обычно, из-за чего данные в нём иногда будут ломаться (т.к. границы слайса не обнуляются).

    Фикс — использовать только []byte или sqlx + sqlx.JSONText (который может быть потенциально опасен).


    1. erlyvideo
      16.01.2016 14:58

      можете пояснить подетальнее в чём проблема?


      1. utrack
        16.01.2016 16:36
        +1

        Всё дело в пуле байт, хранимом sql для снижения нагрузки на GC и алгоритме, применяемом db.Scan():

        If an argument has type *[]byte, Scan saves in that argument a copy of the corresponding data. The copy is owned by the caller and can be modified and held indefinitely. The copy can be avoided by using an argument of type *RawBytes instead; see the documentation for RawBytes for restrictions on its use.

        If an argument has type *interface{}, Scan copies the value provided by the underlying driver without conversion. If the value is of type []byte, a copy is made and the caller owns the result.


        Дело в том, что при передаче в Scan() что-нибудь вроде *json.RawMessage он не видит его как *[]byte, и в итоге поинтер указывает (насколько я понял) на копию слайса, который в свою очередь указывает на массив, который одновременно принадлежит пулу самой *sql.DB.

        Тут небольшое отступление на всякий пожарный: в Го то, что обычно все называют массивом — это слайс, который является чем-то вроде «окна» в массив любой длины (len(slice) <= len(array)). При этом копия слайса всё ещё отображает исходный массив.

        В итоге получается, что в первом вызове Scan() данные опускаются в пустой слайс, который наполняется, помещается в пул и его копия возвращается вам; а при втором вызове sql берёт тот самый грязный слайс из пула и заполняет его новыми данными. Если len(datanew) < len(dataold), то перезаписывается только часть слайса, но возвращается он целиком.

        В итоге, если в БД есть две строки: «12345» и «678», которые вы сосканите друг за другом, то вы получите сперва «12345», а потом «67845». Притом после второго скана первый массив(слайс!) будет хранить тоже «67845».


  1. vitamin
    16.01.2016 16:16
    -3

    Автор, прочитай учебник Новосёлова и прекрати страдать уже. Ванильные сопли, смешно читать, ей богу.


    1. DrPass
      17.01.2016 15:16
      +2

      Вам смешно — не читайте. А мы вот переживаем вместе с автором!


      1. vitamin
        17.01.2016 15:37
        +1

        Так я ж не предлагаю ему не писать. Просто сейчас он эту войну проигрывает. А если воспользуется моим советом, то этот квест с Катей перестанет быть нудным. :) Всем только интересней читать станет.


  1. Gordon01
    17.01.2016 16:50
    +1

    Как то я, в том году нашел сайтик delonevtebe.ru
    Там столько историй про Кать, Маш, Ксюш и даже про Вась )
    Перед сном читать самое то.


    1. monah_tuk
      18.01.2016 07:26
      +4

      Читать название сайта начал как develop…


  1. marenkov
    21.01.2016 17:24

    Сам больше склоняюсь к версии о многопоточности Кати и низком приоритете автора в очереди (как это ни прискорбно). Остальные остальной 1% отдам версии о том, что она принадлежит к тому типу девушек, которых отталкивает хорошее отношение, потому все ее предыдущие парни плохо к ней относились — она сама таких выбирала.