<commit_before>/// [**Experimental**](http://github.com/groue/GRDB.swift#what-are-experimental-features)
///
/// SQLGenerationContext is responsible for preventing SQL injection and
/// disambiguating table names when GRDB generates SQL queries.
///
/// :nodoc:
public struct SQLGenerationContext {
    let db: Database
    var arguments: StatementArguments { argumentsSink.arguments }
    let argumentsSink: StatementArgumentsSink
    private var resolvedNames: [TableAlias: String]
    private var qualifierNeeded: Bool
        
    /// Used for literal generation
    static func sqlLiteralContext(
        _ db: Database,
        argumentsSink: StatementArgumentsSink = StatementArgumentsSink())
        -> SQLGenerationContext
    {
        SQLGenerationContext(
            db: db,
            argumentsSink: argumentsSink,
            resolvedNames: [:],
            qualifierNeeded: false)
    }
    
    /// Used for TableRecord.selectionSQL
    static func selectionContext(
        _ db: Database,
        argumentsSink: StatementArgumentsSink = StatementArgumentsSink())
        -> SQLGenerationContext
    {
        SQLGenerationContext(
            db: db,
            argumentsSink: argumentsSink,
            resolvedNames: [:],
            qualifierNeeded: true)
    }
    
    /// Used for SQLQueryGenerator
    static func queryContext(
        _ db: Database,
        argumentsSink: StatementArgumentsSink = StatementArgumentsSink(),
        aliases: [TableAlias])
        -> SQLGenerationContext
    {
        SQLGenerationContext(
            db: db,
            argumentsSink: argumentsSink,
            resolvedNames: aliases.resolvedNames,
            qualifierNeeded: aliases.count > 1)
    }
    
    /// Returns whether arguments could be appended.
    /// May be false for SQLGenerationContext.rawSQLContext
    func append(arguments: StatementArguments) -> Bool {
        argumentsSink.append(arguments: arguments)
    }
    
    /// May be nil, when a qualifier is not needed:
    ///
    /// WHERE <qualifier>.column == 1
    /// SELECT <qualifier>.*
    ///
    /// WHERE column == 1
    /// SELECT *
    func qualifier(for alias: TableAlias) -> String? {
        if alias.hasUserName {
            return alias.identityName
        }
        if qualifierNeeded == false {
            return nil<commit_msg>Documentation<commit_after>/// [**Experimental**](http://github.com/groue/GRDB.swift#what-are-experimental-features)
///
/// SQLGenerationContext support for SQL generation:
///
/// - It provides a database connection so that request elements can perform
///   database introspection in order to build their SQL representation.
///
/// - It provides an "argumens sink" where request elements can dump database
///   values, in order to prevent SQL injection.
///
/// - It provides unique table aliases in order to disambiguates table names
///   and columns.
///
/// :nodoc:
public struct SQLGenerationContext {
    /// A database connection so that request elements can perform database
    /// introspection in order to build their SQL representation.
    let db: Database
    
    /// An argumens sink where request elements can dump database values, in
    /// order to prevent SQL injection.
    let argumentsSink: StatementArgumentsSink
    
    /// All arguments gathered so far
    var arguments: StatementArguments { argumentsSink.arguments }
    
    private var resolvedNames: [TableAlias: String]
    private var qualifiesColumnsWithTable: Bool
        
    /// Used for literal generation
    static func sqlLiteralContext(
        _ db: Database,
        argumentsSink: StatementArgumentsSink = StatementArgumentsSink())
        -> SQLGenerationContext
    {
        SQLGenerationContext(
            db: db,
            argumentsSink: argumentsSink,
            resolvedNames: [:],
            qualifiesColumnsWithTable: false)
    }
    
    /// Used for SQLQueryGenerator
    static func queryContext(
        _ db: Database,
        argumentsSink: StatementArgumentsSink = StatementArgumentsSink(),
        aliases: [TableAlias])
        -> SQLGenerationContext
    {
        SQLGenerationContext(
            db: db,
            argumentsSink: argumentsSink,
            resolvedNames: aliases.resolvedNames,
            qualifiesColumnsWithTable: aliases.count > 1)
    }
    
    /// Returns whether arguments could be appended.
    /// May be false for SQLGenerationContext.rawSQLContext
    func append(arguments: StatementArguments) -> Bool {
        argumentsSink.append(arguments: arguments)
    }
    
    /// May be nil, when a qualifier is not needed:
    ///
    /// WHERE <qualifier>.column == 1
    /// SELECT <qualifier>.*
    ///
    /// WHERE column == 1
    /// SELECT *
    func qualifier(for alias: TableAlias) -> String? {
        if alias.hasUserName {
            return alias.identityName
        }
        if qualifiesColumnsWithTable == false {
            return nil
{'fraction_non_alphanumeric': 0.0890729145627146, 'fraction_numerical': 0.001211876388608362, 'mean_word_length': 2.266490765171504, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 18, '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': '5449602', 'n_tokens_mistral': 1209, 'n_tokens_neox': 1217, 'n_words': 368}