Skip to content

Commit

Permalink
Merge pull request #404 from mk3008/402-add-class-function-and-proper…
Browse files Browse the repository at this point in the history
…ty-comments

Add comment
  • Loading branch information
mk3008 authored May 7, 2024
2 parents 9ba70ba + 8018395 commit 02a412c
Show file tree
Hide file tree
Showing 21 changed files with 378 additions and 54 deletions.
22 changes: 18 additions & 4 deletions src/Carbunql/Analysis/AlterTableQueryParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,37 @@

namespace Carbunql.Analysis;

/// <summary>
/// Provides methods for parsing ALTER TABLE queries from SQL token streams.
/// </summary>
public static class AlterTableQueryParser
{
/// <summary>
/// Parses an ALTER TABLE query from SQL text.
/// </summary>
/// <param name="text">The SQL text to parse.</param>
/// <returns>The parsed ALTER TABLE query.</returns>
public static AlterTableQuery Parse(string text)
{
var r = new SqlTokenReader(text);
var q = Parse(r);
var query = Parse(r);

// If there are unparsed tokens remaining, it indicates an issue with parsing.
if (!r.Peek().IsEndToken())
{
throw new NotSupportedException($"Parsing terminated despite the presence of unparsed tokens.(token:'{r.Peek()}')");
throw new NotSupportedException($"Parsing terminated despite the presence of unparsed tokens. (Token: '{r.Peek()}')");
}

return q;
return query;
}

/// <summary>
/// Parses an ALTER TABLE query from a token reader.
/// </summary>
/// <param name="r">The token reader.</param>
/// <returns>The parsed ALTER TABLE query.</returns>
public static AlterTableQuery Parse(ITokenReader r)
{
return new AlterTableQuery(AlterTableClauseParser.Parse(r));
}
}
}
38 changes: 36 additions & 2 deletions src/Carbunql/Analysis/BracketInnerTokenReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@

namespace Carbunql.Analysis;

/// <summary>
/// Token reader for reading tokens within brackets.
/// </summary>
public class BracketInnerTokenReader : ITokenReader, IDisposable
{
/// <summary>
/// Gets or sets the start symbol indicating the beginning of the bracket.
/// </summary>
private string StartSymbol { get; init; } = "(";

/// <summary>
/// Gets or sets the end symbol indicating the end of the bracket.
/// </summary>
private string EndSymbol { get; init; } = ")";

/// <summary>
/// Initializes a new instance of the <see cref="BracketInnerTokenReader"/> class with custom start and end symbols.
/// </summary>
/// <param name="r">The token reader to use.</param>
/// <param name="startSymbol">The start symbol indicating the beginning of the bracket.</param>
/// <param name="endSymbol">The end symbol indicating the end of the bracket.</param>
public BracketInnerTokenReader(ITokenReader r, string startSymbol, string endSymbol)
{
StartSymbol = startSymbol;
Expand All @@ -20,6 +35,10 @@ public BracketInnerTokenReader(ITokenReader r, string startSymbol, string endSym
RootBracketLevel = r.CurrentBracketLevel;
}

/// <summary>
/// Initializes a new instance of the <see cref="BracketInnerTokenReader"/> class with default start and end symbols.
/// </summary>
/// <param name="r">The token reader to use.</param>
public BracketInnerTokenReader(ITokenReader r)
{
r.Read(StartSymbol);
Expand All @@ -28,21 +47,33 @@ public BracketInnerTokenReader(ITokenReader r)
RootBracketLevel = r.CurrentBracketLevel;
}

/// <summary>
/// Gets the token reader.
/// </summary>
private ITokenReader Reader { get; set; }

/// <summary>
/// Gets the root bracket level.
/// </summary>
private int RootBracketLevel { get; set; }

/// <inheritdoc/>
public int CurrentBracketLevel => Reader.CurrentBracketLevel;

/// <summary>
/// Gets or sets a value indicating whether the reading process is terminated.
/// </summary>
private bool IsTerminated { get; set; } = false;

/// <inheritdoc/>
public string Peek()
{
if (IsTerminated) return string.Empty;

return Reader.Peek();
}

/// <inheritdoc/>
public string Read()
{
if (IsTerminated) return string.Empty;
Expand All @@ -55,16 +86,19 @@ public string Read()
return token;
}

/// <inheritdoc/>
public void Dispose()
{
Reader.Read(EndSymbol);
}

/// <inheritdoc/>
public void RollBack()
{
throw new NotImplementedException();
}

/// <inheritdoc/>
public bool TryRead(string expect, [MaybeNullWhen(false)] out string token)
{
token = null;
Expand All @@ -74,6 +108,6 @@ public bool TryRead(string expect, [MaybeNullWhen(false)] out string token)
token = Read();
return true;
}
return false; ;
return false;
}
}
}
34 changes: 31 additions & 3 deletions src/Carbunql/Analysis/CreateIndexQueryParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,34 @@

namespace Carbunql.Analysis;

/// <summary>
/// Provides functionality to parse CREATE INDEX queries in SQL.
/// </summary>
public static class CreateIndexQueryParser
{
/// <summary>
/// Parses the specified CREATE INDEX query string.
/// </summary>
/// <param name="text">The CREATE INDEX query string.</param>
/// <returns>The parsed CreateIndexQuery object.</returns>
public static CreateIndexQuery Parse(string text)
{
var r = new SqlTokenReader(text);
var q = Parse(r);

if (!r.Peek().IsEndToken())
{
throw new NotSupportedException($"Parsing terminated despite the presence of unparsed tokens.(token:'{r.Peek()}')");
throw new NotSupportedException($"Parsing terminated despite the presence of unparsed tokens. (Token: '{r.Peek()}')");
}

return q;
}

/// <summary>
/// Parses the CREATE INDEX query using the provided ITokenReader.
/// </summary>
/// <param name="r">The ITokenReader instance.</param>
/// <returns>The parsed CreateIndexQuery object.</returns>
public static CreateIndexQuery Parse(ITokenReader r)
{
var t = ParseAsCreateIndexCommand(r);
Expand All @@ -30,6 +43,11 @@ public static CreateIndexQuery Parse(ITokenReader r)
return t;
}

/// <summary>
/// Parses the CREATE INDEX command.
/// </summary>
/// <param name="r">The ITokenReader instance.</param>
/// <returns>The parsed CreateIndexQuery object.</returns>
private static CreateIndexQuery ParseAsCreateIndexCommand(ITokenReader r)
{
var isUnique = false;
Expand All @@ -44,7 +62,7 @@ private static CreateIndexQuery ParseAsCreateIndexCommand(ITokenReader r)
}
else
{
throw new NotSupportedException($"Token:{token}");
throw new NotSupportedException($"Invalid CREATE INDEX command. (Token: '{token}')");
}

var indexName = string.Empty;
Expand All @@ -61,6 +79,11 @@ private static CreateIndexQuery ParseAsCreateIndexCommand(ITokenReader r)
};
}

/// <summary>
/// Parses the ON clause of the CREATE INDEX query.
/// </summary>
/// <param name="r">The ITokenReader instance.</param>
/// <returns>The parsed IndexOnClause object.</returns>
private static IndexOnClause ParseAsOnClause(ITokenReader r)
{
r.Read("on");
Expand All @@ -85,6 +108,11 @@ private static IndexOnClause ParseAsOnClause(ITokenReader r)
return clause;
}

/// <summary>
/// Parses the table name in the ON clause of the CREATE INDEX query.
/// </summary>
/// <param name="r">The ITokenReader instance.</param>
/// <returns>The parsed table name and schema as a tuple.</returns>
private static (string schema, string name) ParseAsTableName(ITokenReader r)
{
var token = r.Read();
Expand All @@ -104,4 +132,4 @@ private static (string schema, string name) ParseAsTableName(ITokenReader r)

return (schema, name);
}
}
}
31 changes: 26 additions & 5 deletions src/Carbunql/Analysis/CreateTableQueryParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@

namespace Carbunql.Analysis;

/// <summary>
/// Provides functionality to parse CREATE TABLE queries in SQL.
/// </summary>
public static class CreateTableQueryParser
{
/// <summary>
/// Parses the specified CREATE TABLE query string.
/// </summary>
/// <param name="text">The CREATE TABLE query string.</param>
/// <returns>The parsed CreateTableQuery object.</returns>
public static CreateTableQuery Parse(string text)
{
var r = new SqlTokenReader(text);
var q = Parse(r);

if (!r.Peek().IsEndToken())
{
throw new NotSupportedException($"Parsing terminated despite the presence of unparsed tokens.(token:'{r.Peek()}')");
throw new NotSupportedException($"Parsing terminated despite the presence of unparsed tokens. (Token: '{r.Peek()}')");
}

return q;
}

static IEnumerable<string> ConstraintTokens => new[] { "primary key", "unique", "foreign key", "check", "not null", "constraint" };

/// <summary>
/// Parses the CREATE TABLE query using the provided ITokenReader.
/// </summary>
/// <param name="r">The ITokenReader instance.</param>
/// <returns>The parsed CreateTableQuery object.</returns>
public static CreateTableQuery Parse(ITokenReader r)
{
var t = ParseAsCreateTableCommand(r);
Expand Down Expand Up @@ -56,6 +67,16 @@ public static CreateTableQuery Parse(ITokenReader r)
return t;
}

/// <summary>
/// The tokens representing constraints in CREATE TABLE queries.
/// </summary>
private static IEnumerable<string> ConstraintTokens => new[] { "primary key", "unique", "foreign key", "check", "not null", "constraint" };

/// <summary>
/// Parses the CREATE TABLE command.
/// </summary>
/// <param name="r">The ITokenReader instance.</param>
/// <returns>The parsed CreateTableQuery object.</returns>
private static CreateTableQuery ParseAsCreateTableCommand(ITokenReader r)
{
var isTemporary = false;
Expand All @@ -70,7 +91,7 @@ private static CreateTableQuery ParseAsCreateTableCommand(ITokenReader r)
}
else
{
throw new NotSupportedException($"Token:{token}");
throw new NotSupportedException($"Invalid CREATE TABLE command. (Token: '{token}')");
}

token = r.Read();
Expand All @@ -89,4 +110,4 @@ private static CreateTableQuery ParseAsCreateTableCommand(ITokenReader r)

return new CreateTableQuery(schema, table) { IsTemporary = isTemporary };
}
}
}
18 changes: 16 additions & 2 deletions src/Carbunql/Analysis/DefinitionQuerySetParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@

namespace Carbunql.Analysis;

/// <summary>
/// Provides functionality to parse a set of definition queries in SQL.
/// </summary>
public static class DefinitionQuerySetParser
{
/// <summary>
/// Parses the specified definition query string and returns a list of DefinitionQuerySet objects.
/// </summary>
/// <param name="text">The definition query string.</param>
/// <returns>A list of DefinitionQuerySet objects.</returns>
public static DefinitionQuerySetList Parse(string text)
{
var r = new SqlTokenReader(text);
Expand All @@ -15,7 +23,7 @@ public static DefinitionQuerySetList Parse(string text)
{
if (!r.Peek().IsEndToken())
{
throw new NotSupportedException($"Parsing terminated despite the presence of unparsed tokens.(token:'{r.Peek()}')");
throw new NotSupportedException($"Parsing terminated despite the presence of unparsed tokens. (Token: '{r.Peek()}')");
}

if (!dic.ContainsKey(t.GetTableFullName()))
Expand All @@ -38,7 +46,7 @@ public static DefinitionQuerySetList Parse(string text)
}
else
{
throw new NotSupportedException();
throw new NotSupportedException($"Unsupported query type: {t.GetType().Name}");
}
}

Expand All @@ -47,6 +55,12 @@ public static DefinitionQuerySetList Parse(string text)
return lst;
}

/// <summary>
/// Tries to parse the next query from the token reader.
/// </summary>
/// <param name="r">The SqlTokenReader instance.</param>
/// <param name="t">The parsed table object.</param>
/// <returns>True if parsing is successful, otherwise false.</returns>
private static bool TryParse(SqlTokenReader r, [MaybeNullWhen(false)] out ITable t)
{
t = default;
Expand Down
Loading

0 comments on commit 02a412c

Please sign in to comment.