<commit_before>package sql

import (
	"bytes"
	"database/sql"
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"gnd.la/app/profile"
	"gnd.la/config"
	"gnd.la/encoding/codec"
	"gnd.la/encoding/pipe"
	"gnd.la/internal"
	"gnd.la/log"
	"gnd.la/orm/driver"
	"gnd.la/orm/index"
	"gnd.la/orm/operation"
	"gnd.la/orm/query"
	"gnd.la/util/structs"
)

var (
	stringType   = reflect.TypeOf("")
	subqueryType = reflect.TypeOf(query.Subquery(""))
)

type Driver struct {
	db         *DB
	logger     *log.Logger
	backend    Backend
	transforms map[reflect.Type]struct{}
}

func (d *Driver) Check() error {
	if err := d.db.sqlDb.Ping(); err != nil {
		return err
	}
	return d.backend.Check(d.db)
}

func (d *Driver) Initialize(ms []driver.Model) error {
	// Create tables
	for _, v := range ms {
		tbl, err := d.makeTable(v)
		if err != nil {
			return err
		}
		existingTbl, err := d.backend.Inspect(d.db, v)
		if err != nil {
			return err
		}
		if existingTbl != nil {
			err = d.mergeTable(v, existingTbl, tbl)
		} else {
			if len(tbl.Fields) == 0 {
				log.Debugf("Skipping collection %s (model %v) because it has no fields", v.Table, v)
				continue
			}
			// Table does not exists, create it
			err = d.createTable(v, tbl)
		}
		if err != nil {
			return err
		}
	}
	// Create indexes
	for _, v := range ms {
		if err := d.createIndexes(v); err != nil {
			return err
		}
	}
	return nil
}

func (d *Driver) createIndexes(m driver.Model) error {
	for _, idx := range m.Indexes() {
		name, err := d.indexName(m, idx)
		if err != nil {
			return err
		}
		if err := d.createIndex(m, idx, name); err != nil {
			return err
		}
	}
	return nil
}

func (d *Driver) createIndex(m driver.Model, idx *index.Index, name string) error {
	has, err := d.backend.HasIndex(d.db, m, idx, name)
	if err != nil {
		return err
	}
	if has {
		return nil
	}

	buf := getBuffer()
	buf.WriteString("CREATE ")
	if idx.Unique {
		buf.WriteString("UNIQUE ")
	}
	buf.WriteString("INDEX ")
	buf.WriteString(name)
	buf.WriteString(" ON \"")
	buf.WriteString(m.Table())
	buf.WriteString("\" (")
	fields := m.Fields()
	for _, v := range idx.Fields {
		name, _, err := fields.Map(v)
		if err != nil {
			return err
		}
		buf.WriteString(name)
		if DescField(idx, v) {
			buf.WriteString(" DESC")
		}
		buf.WriteByte(',')
	}
	buf.Truncate(buf.Len() - 1)<commit_msg>Correctly quote field names in indexes<commit_after>package sql

import (
	"bytes"
	"database/sql"
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"gnd.la/app/profile"
	"gnd.la/config"
	"gnd.la/encoding/codec"
	"gnd.la/encoding/pipe"
	"gnd.la/internal"
	"gnd.la/log"
	"gnd.la/orm/driver"
	"gnd.la/orm/index"
	"gnd.la/orm/operation"
	"gnd.la/orm/query"
	"gnd.la/util/structs"
)

var (
	stringType   = reflect.TypeOf("")
	subqueryType = reflect.TypeOf(query.Subquery(""))
)

type Driver struct {
	db         *DB
	logger     *log.Logger
	backend    Backend
	transforms map[reflect.Type]struct{}
}

func (d *Driver) Check() error {
	if err := d.db.sqlDb.Ping(); err != nil {
		return err
	}
	return d.backend.Check(d.db)
}

func (d *Driver) Initialize(ms []driver.Model) error {
	// Create tables
	for _, v := range ms {
		tbl, err := d.makeTable(v)
		if err != nil {
			return err
		}
		existingTbl, err := d.backend.Inspect(d.db, v)
		if err != nil {
			return err
		}
		if existingTbl != nil {
			err = d.mergeTable(v, existingTbl, tbl)
		} else {
			if len(tbl.Fields) == 0 {
				log.Debugf("Skipping collection %s (model %v) because it has no fields", v.Table, v)
				continue
			}
			// Table does not exists, create it
			err = d.createTable(v, tbl)
		}
		if err != nil {
			return err
		}
	}
	// Create indexes
	for _, v := range ms {
		if err := d.createIndexes(v); err != nil {
			return err
		}
	}
	return nil
}

func (d *Driver) createIndexes(m driver.Model) error {
	for _, idx := range m.Indexes() {
		name, err := d.indexName(m, idx)
		if err != nil {
			return err
		}
		if err := d.createIndex(m, idx, name); err != nil {
			return err
		}
	}
	return nil
}

func (d *Driver) createIndex(m driver.Model, idx *index.Index, name string) error {
	has, err := d.backend.HasIndex(d.db, m, idx, name)
	if err != nil {
		return err
	}
	if has {
		return nil
	}

	buf := getBuffer()
	buf.WriteString("CREATE ")
	if idx.Unique {
		buf.WriteString("UNIQUE ")
	}
	buf.WriteString("INDEX ")
	buf.WriteString(name)
	buf.WriteString(" ON \"")
	buf.WriteString(m.Table())
	buf.WriteString("\" (")
	fields := m.Fields()
	for _, v := range idx.Fields {
		name, _, err := fields.Map(v)
		if err != nil {
			return err
		}
		buf.WriteByte('"')
		buf.WriteString(name)
		buf.WriteByte('"')
		if DescField(idx, v) {
			buf.WriteString(" DESC")
		}
		buf.WriteByte(',')
	}
	buf.Truncate(buf.Len() - 1)
{'fraction_non_alphanumeric': 0.1650010631511801, 'fraction_numerical': 0.0008505209440782479, 'mean_word_length': 2.9529411764705884, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3916034', 'n_tokens_mistral': 2027, 'n_tokens_neox': 1889, 'n_words': 450}