Question

Sorry for dumb question.

I have some kind of SQL schema, that looks like this (for example):

create table test_table (
    id integer not null,
    title text,
    primary key ("id")
);

create table test_table2 (
    id integer not null,
    subtitle text,
    some_wierd_count integer not null,
    primary key ("id")
);

From this schema I need only some information. I don't care about primary keys, indeces, "not null"s. Just table name, fields names and types.

I wrote following ugly code, that doesn't work: http://code.sdfgh153.ru/gimme-models/src/1e5a17f2f8dbc225b0d26da405f5a1303f896ddb/src/GimmeModels/Schema/SQLSchema/Parser.hs?at=default

As I thought this code should fill in this types:

data Schema = Schema { schemaTables :: [Table] } deriving (Show)

data Table = Table {
      tableName   :: String 
    , tableFields :: [Field]
    } deriving (Show)

data Field = Field {
      fieldName :: String
    , fieldType :: String
    } deriving (Show)

But can't figure it out, how to properly parse fields section inside create table expression. How should I detect end of field declaration?

Was it helpful?

Solution

Ok, with kelp of kqr I finally realized: I should use sepBy combinator. My final code to parse table with fields declarations:

tableParser :: P.Parser Table
tableParser = do
    P.manyTill P.anyChar $ P.stringCI "create table"
    P.skipWhile fieldGarbage
    n <- P.takeWhile (not . fieldGarbage)
    P.skipWhile fieldGarbage 
    P.char '(' 
    fs <- fieldParser `P.sepBy` P.char ','
    P.manyTill P.anyChar (P.char ';')
    return $ Table (C.unpack n) fs 

parseStr = do 
    P.skipWhile fieldGarbage
    P.takeWhile (not . fieldGarbage)

fieldParser :: P.Parser Field
fieldParser = do
    n <- parseStr
    t <- parseStr 
    P.takeTill (\c -> c == ',' || c == ';')
    return $ Field (C.unpack n) (C.unpack t)

Thank you all for the help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top